[
  {
    "path": ".fastRequest/collections/Root/Default Group/directory.json",
    "content": "{\n\t\"description\":\"\",\n\t\"directory\":\"~.fastRequest~collections~Root~Default Group\",\n\t\"filePath\":\"~.fastRequest~collections~Root~Default Group~\",\n\t\"groupId\":\"1\",\n\t\"id\":\"1\",\n\t\"name\":\"Default Group\",\n\t\"type\":1\n}"
  },
  {
    "path": ".fastRequest/collections/Root/directory.json",
    "content": "{\n\t\"description\":\"\",\n\t\"directory\":\"~.fastRequest~collections~Root\",\n\t\"filePath\":\"~.fastRequest~collections~Root~\",\n\t\"groupId\":\"-1\",\n\t\"id\":\"0\",\n\t\"name\":\"Root\",\n\t\"type\":1\n}"
  },
  {
    "path": ".fastRequest/config/fastRequestCurrentProjectConfig.json",
    "content": "{\n\t\"dataList\":[\n\t\t{\n\t\t\t\"hostGroup\":[\n\t\t\t\t{\n\t\t\t\t\t\"env\":\"App\",\n\t\t\t\t\t\"url\":\"api.co\"\n\t\t\t\t}\n\t\t\t],\n\t\t\t\"name\":\"App\"\n\t\t}\n\t],\n\t\"envList\":[\n\t\t\"App\"\n\t],\n\t\"headerList\":[],\n\t\"postScript\":\"\",\n\t\"preScript\":\"\",\n\t\"projectList\":[\n\t\t\"App\"\n\t],\n\t\"syncModel\":{\n\t\t\"branch\":\"master\",\n\t\t\"domain\":\"https://github.com\",\n\t\t\"enabled\":false,\n\t\t\"namingPolicy\":\"byDoc\",\n\t\t\"owner\":\"\",\n\t\t\"repo\":\"\",\n\t\t\"repoUrl\":\"\",\n\t\t\"syncAfterRun\":false,\n\t\t\"token\":\"\",\n\t\t\"type\":\"github\"\n\t},\n\t\"urlEncodedKeyValueList\":[],\n\t\"urlParamsKeyValueList\":[],\n\t\"urlSuffix\":\"\"\n}"
  },
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".gitignore",
    "content": "# Compiled class file\n*.class\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for Java (J2ME)\n.mtj.tmp/\n\n# Package Files #\n*.jar\n*.war\n*.nar\n*.ear\n*.zip\n*.tar.gz\n*.rar\n\n# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml\nhs_err_pid*\nreplay_pid*\n"
  },
  {
    "path": ".gradle/8.2/dependencies-accessors/gc.properties",
    "content": ""
  },
  {
    "path": ".gradle/8.2/gc.properties",
    "content": ""
  },
  {
    "path": ".gradle/buildOutputCleanup/cache.properties",
    "content": "#Mon Jan 08 18:49:54 CST 2024\ngradle.version=8.2\n"
  },
  {
    "path": ".gradle/config.properties",
    "content": "#Mon Dec 11 18:47:37 CST 2023\njava.home=C\\:\\\\Program Files\\\\Android\\\\Android Studio\\\\jbr\n"
  },
  {
    "path": ".gradle/vcs-1/gc.properties",
    "content": ""
  },
  {
    "path": ".idea/.gitignore",
    "content": "# Default ignored files\n/shelf/\n/workspace.xml\n"
  },
  {
    "path": ".idea/assetWizardSettings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"WizardSettings\">\n    <option name=\"children\">\n      <map>\n        <entry key=\"imageWizard\">\n          <value>\n            <PersistentState>\n              <option name=\"children\">\n                <map>\n                  <entry key=\"imageAssetPanel\">\n                    <value>\n                      <PersistentState>\n                        <option name=\"children\">\n                          <map>\n                            <entry key=\"actionbar\">\n                              <value>\n                                <PersistentState>\n                                  <option name=\"children\">\n                                    <map>\n                                      <entry key=\"clipArt\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"imagePath\" value=\"C:\\Users\\ShihCheeng\\AppData\\Local\\Temp\\baseline_person_outline_24.xml\" />\n                                                <entry key=\"opacityPercent\" value=\"60\" />\n                                                <entry key=\"paddingPercent\" value=\"10\" />\n                                                <entry key=\"trimmed\" value=\"true\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"clipartAsset\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"url\" value=\"file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/person_outline/baseline_person_outline_24.xml\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"image\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"opacityPercent\" value=\"60\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"text\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"opacityPercent\" value=\"60\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"textAsset\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"opacityPercent\" value=\"60\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                    </map>\n                                  </option>\n                                  <option name=\"values\">\n                                    <map>\n                                      <entry key=\"outputName\" value=\"ic_person_center\" />\n                                    </map>\n                                  </option>\n                                </PersistentState>\n                              </value>\n                            </entry>\n                            <entry key=\"launcher\">\n                              <value>\n                                <PersistentState>\n                                  <option name=\"children\">\n                                    <map>\n                                      <entry key=\"foregroundClipArt\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"imagePath\" value=\"C:\\Users\\ShihCheeng\\AppData\\Local\\Temp\\ic_android_black_24dp.xml\" />\n                                                <entry key=\"trimmed\" value=\"true\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"foregroundImage\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"imagePath\" value=\"C:\\Users\\ShihCheeng\\Desktop\\开发\\xuelunyan.png\" />\n                                                <entry key=\"scalingPercent\" value=\"56\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"foregroundText\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"trimmed\" value=\"true\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"foregroundTextAsset\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"trimmed\" value=\"true\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                    </map>\n                                  </option>\n                                  <option name=\"values\">\n                                    <map>\n                                      <entry key=\"backgroundAssetType\" value=\"COLOR\" />\n                                      <entry key=\"outputName\" value=\"ic_copy\" />\n                                    </map>\n                                  </option>\n                                </PersistentState>\n                              </value>\n                            </entry>\n                            <entry key=\"launcherLegacy\">\n                              <value>\n                                <PersistentState>\n                                  <option name=\"children\">\n                                    <map>\n                                      <entry key=\"clipArt\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"imagePath\" value=\"C:\\Users\\ShihCheeng\\AppData\\Local\\Temp\\ic_android_black_24dp.xml\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"text\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"textAsset\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                    </map>\n                                  </option>\n                                </PersistentState>\n                              </value>\n                            </entry>\n                            <entry key=\"notification\">\n                              <value>\n                                <PersistentState>\n                                  <option name=\"children\">\n                                    <map>\n                                      <entry key=\"clipArt\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"imagePath\" value=\"C:\\Users\\ShihCheeng\\AppData\\Local\\Temp\\ic_android_black_24dp.xml\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"image\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                                <entry key=\"imagePath\" value=\"C:\\Users\\ShihCheeng\\Desktop\\开发\\xuelunyan.png\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"text\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"textAsset\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                    </map>\n                                  </option>\n                                  <option name=\"values\">\n                                    <map>\n                                      <entry key=\"assetType\" value=\"IMAGE\" />\n                                      <entry key=\"imageAsset\" value=\"C:\\Users\\ShihCheeng\\Desktop\\开发\\xuelunyan.png\" />\n                                    </map>\n                                  </option>\n                                </PersistentState>\n                              </value>\n                            </entry>\n                            <entry key=\"tvBanner\">\n                              <value>\n                                <PersistentState>\n                                  <option name=\"children\">\n                                    <map>\n                                      <entry key=\"foregroundText\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                    </map>\n                                  </option>\n                                </PersistentState>\n                              </value>\n                            </entry>\n                            <entry key=\"tvChannel\">\n                              <value>\n                                <PersistentState>\n                                  <option name=\"children\">\n                                    <map>\n                                      <entry key=\"foregroundClipArt\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"imagePath\" value=\"C:\\Users\\ShihCheeng\\AppData\\Local\\Temp\\ic_android_black_24dp.xml\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"foregroundImage\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"foregroundText\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                      <entry key=\"foregroundTextAsset\">\n                                        <value>\n                                          <PersistentState>\n                                            <option name=\"values\">\n                                              <map>\n                                                <entry key=\"color\" value=\"000000\" />\n                                              </map>\n                                            </option>\n                                          </PersistentState>\n                                        </value>\n                                      </entry>\n                                    </map>\n                                  </option>\n                                </PersistentState>\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                        <option name=\"values\">\n                          <map>\n                            <entry key=\"outputIconType\" value=\"NOTIFICATION\" />\n                          </map>\n                        </option>\n                      </PersistentState>\n                    </value>\n                  </entry>\n                </map>\n              </option>\n            </PersistentState>\n          </value>\n        </entry>\n        <entry key=\"vectorWizard\">\n          <value>\n            <PersistentState>\n              <option name=\"children\">\n                <map>\n                  <entry key=\"vectorAssetStep\">\n                    <value>\n                      <PersistentState>\n                        <option name=\"children\">\n                          <map>\n                            <entry key=\"clipartAsset\">\n                              <value>\n                                <PersistentState>\n                                  <option name=\"values\">\n                                    <map>\n                                      <entry key=\"url\" value=\"file:/$USER_HOME$/AppData/Local/Android/Sdk/icons/material/materialicons/replay/baseline_replay_24.xml\" />\n                                    </map>\n                                  </option>\n                                </PersistentState>\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                        <option name=\"values\">\n                          <map>\n                            <entry key=\"outputName\" value=\"baseline_replay_24\" />\n                            <entry key=\"sourceFile\" value=\"C:\\Users\\ShihCheeng\\Downloads\\undraw_personal_file_re_5joy.svg\" />\n                          </map>\n                        </option>\n                      </PersistentState>\n                    </value>\n                  </entry>\n                </map>\n              </option>\n            </PersistentState>\n          </value>\n        </entry>\n      </map>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <DBN-PSQL>\n      <case-options enabled=\"true\">\n        <option name=\"KEYWORD_CASE\" value=\"lower\" />\n        <option name=\"FUNCTION_CASE\" value=\"lower\" />\n        <option name=\"PARAMETER_CASE\" value=\"lower\" />\n        <option name=\"DATATYPE_CASE\" value=\"lower\" />\n        <option name=\"OBJECT_CASE\" value=\"preserve\" />\n      </case-options>\n      <formatting-settings enabled=\"false\" />\n    </DBN-PSQL>\n    <DBN-SQL>\n      <case-options enabled=\"true\">\n        <option name=\"KEYWORD_CASE\" value=\"lower\" />\n        <option name=\"FUNCTION_CASE\" value=\"lower\" />\n        <option name=\"PARAMETER_CASE\" value=\"lower\" />\n        <option name=\"DATATYPE_CASE\" value=\"lower\" />\n        <option name=\"OBJECT_CASE\" value=\"preserve\" />\n      </case-options>\n      <formatting-settings enabled=\"false\">\n        <option name=\"STATEMENT_SPACING\" value=\"one_line\" />\n        <option name=\"CLAUSE_CHOP_DOWN\" value=\"chop_down_if_statement_long\" />\n        <option name=\"ITERATION_ELEMENTS_WRAPPING\" value=\"chop_down_if_not_single\" />\n      </formatting-settings>\n    </DBN-SQL>\n    <codeStyleSettings language=\"XML\">\n      <option name=\"FORCE_REARRANGE_MODE\" value=\"1\" />\n      <indentOptions>\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      </indentOptions>\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/codeStyles/codeStyleConfig.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <state>\n    <option name=\"PREFERRED_PROJECT_CODE_STYLE\" value=\"Default\" />\n  </state>\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=\"17\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/dbnavigator.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"DBNavigator.Project.DDLFileAttachmentManager\">\n    <mappings />\n    <preferences />\n  </component>\n  <component name=\"DBNavigator.Project.DataEditorManager\">\n    <record-view-column-sorting-type value=\"BY_INDEX\" />\n    <value-preview-text-wrapping value=\"false\" />\n    <value-preview-pinned value=\"false\" />\n  </component>\n  <component name=\"DBNavigator.Project.DataExportManager\">\n    <export-instructions>\n      <create-header value=\"true\" />\n      <friendly-headers value=\"false\" />\n      <quote-values-containing-separator value=\"true\" />\n      <quote-all-values value=\"false\" />\n      <value-separator value=\"\" />\n      <file-name value=\"\" />\n      <file-location value=\"\" />\n      <scope value=\"GLOBAL\" />\n      <destination value=\"FILE\" />\n      <format value=\"EXCEL\" />\n      <charset value=\"GBK\" />\n      <charset value=\"GBK\" />\n    </export-instructions>\n  </component>\n  <component name=\"DBNavigator.Project.DatabaseBrowserManager\">\n    <autoscroll-to-editor value=\"false\" />\n    <autoscroll-from-editor value=\"true\" />\n    <show-object-properties value=\"true\" />\n    <loaded-nodes />\n  </component>\n  <component name=\"DBNavigator.Project.DatabaseEditorStateManager\">\n    <last-used-providers />\n  </component>\n  <component name=\"DBNavigator.Project.DatabaseFileManager\">\n    <open-files />\n  </component>\n  <component name=\"DBNavigator.Project.EditorStateManager\">\n    <last-used-providers />\n  </component>\n  <component name=\"DBNavigator.Project.ExecutionManager\">\n    <retain-sticky-names value=\"false\" />\n  </component>\n  <component name=\"DBNavigator.Project.MethodExecutionManager\">\n    <method-browser />\n    <execution-history>\n      <group-entries value=\"true\" />\n      <execution-inputs />\n    </execution-history>\n    <argument-values-cache />\n  </component>\n  <component name=\"DBNavigator.Project.ObjectDependencyManager\">\n    <last-used-dependency-type value=\"INCOMING\" />\n  </component>\n  <component name=\"DBNavigator.Project.ObjectQuickFilterManager\">\n    <last-used-operator value=\"EQUAL\" />\n    <filters />\n  </component>\n  <component name=\"DBNavigator.Project.ParserDiagnosticsManager\">\n    <diagnostics-history />\n  </component>\n  <component name=\"DBNavigator.Project.ScriptExecutionManager\" clear-outputs=\"true\">\n    <recently-used-interfaces />\n  </component>\n  <component name=\"DBNavigator.Project.Settings\">\n    <connections />\n    <browser-settings>\n      <general>\n        <display-mode value=\"TABBED\" />\n        <navigation-history-size value=\"100\" />\n        <show-object-details value=\"false\" />\n      </general>\n      <filters>\n        <object-type-filter>\n          <object-type name=\"SCHEMA\" enabled=\"true\" />\n          <object-type name=\"USER\" enabled=\"true\" />\n          <object-type name=\"ROLE\" enabled=\"true\" />\n          <object-type name=\"PRIVILEGE\" enabled=\"true\" />\n          <object-type name=\"CHARSET\" enabled=\"true\" />\n          <object-type name=\"TABLE\" enabled=\"true\" />\n          <object-type name=\"VIEW\" enabled=\"true\" />\n          <object-type name=\"MATERIALIZED_VIEW\" enabled=\"true\" />\n          <object-type name=\"NESTED_TABLE\" enabled=\"true\" />\n          <object-type name=\"COLUMN\" enabled=\"true\" />\n          <object-type name=\"INDEX\" enabled=\"true\" />\n          <object-type name=\"CONSTRAINT\" enabled=\"true\" />\n          <object-type name=\"DATASET_TRIGGER\" enabled=\"true\" />\n          <object-type name=\"DATABASE_TRIGGER\" enabled=\"true\" />\n          <object-type name=\"SYNONYM\" enabled=\"true\" />\n          <object-type name=\"SEQUENCE\" enabled=\"true\" />\n          <object-type name=\"PROCEDURE\" enabled=\"true\" />\n          <object-type name=\"FUNCTION\" enabled=\"true\" />\n          <object-type name=\"PACKAGE\" enabled=\"true\" />\n          <object-type name=\"TYPE\" enabled=\"true\" />\n          <object-type name=\"TYPE_ATTRIBUTE\" enabled=\"true\" />\n          <object-type name=\"ARGUMENT\" enabled=\"true\" />\n          <object-type name=\"DIMENSION\" enabled=\"true\" />\n          <object-type name=\"CLUSTER\" enabled=\"true\" />\n          <object-type name=\"DBLINK\" enabled=\"true\" />\n        </object-type-filter>\n      </filters>\n      <sorting>\n        <object-type name=\"COLUMN\" sorting-type=\"NAME\" />\n        <object-type name=\"FUNCTION\" sorting-type=\"NAME\" />\n        <object-type name=\"PROCEDURE\" sorting-type=\"NAME\" />\n        <object-type name=\"ARGUMENT\" sorting-type=\"POSITION\" />\n        <object-type name=\"TYPE ATTRIBUTE\" sorting-type=\"POSITION\" />\n      </sorting>\n      <default-editors>\n        <object-type name=\"VIEW\" editor-type=\"SELECTION\" />\n        <object-type name=\"PACKAGE\" editor-type=\"SELECTION\" />\n        <object-type name=\"TYPE\" editor-type=\"SELECTION\" />\n      </default-editors>\n    </browser-settings>\n    <navigation-settings>\n      <lookup-filters>\n        <lookup-objects>\n          <object-type name=\"SCHEMA\" enabled=\"true\" />\n          <object-type name=\"USER\" enabled=\"false\" />\n          <object-type name=\"ROLE\" enabled=\"false\" />\n          <object-type name=\"PRIVILEGE\" enabled=\"false\" />\n          <object-type name=\"CHARSET\" enabled=\"false\" />\n          <object-type name=\"TABLE\" enabled=\"true\" />\n          <object-type name=\"VIEW\" enabled=\"true\" />\n          <object-type name=\"MATERIALIZED VIEW\" enabled=\"true\" />\n          <object-type name=\"INDEX\" enabled=\"true\" />\n          <object-type name=\"CONSTRAINT\" enabled=\"true\" />\n          <object-type name=\"DATASET TRIGGER\" enabled=\"true\" />\n          <object-type name=\"DATABASE TRIGGER\" enabled=\"true\" />\n          <object-type name=\"SYNONYM\" enabled=\"false\" />\n          <object-type name=\"SEQUENCE\" enabled=\"true\" />\n          <object-type name=\"PROCEDURE\" enabled=\"true\" />\n          <object-type name=\"FUNCTION\" enabled=\"true\" />\n          <object-type name=\"PACKAGE\" enabled=\"true\" />\n          <object-type name=\"TYPE\" enabled=\"true\" />\n          <object-type name=\"DIMENSION\" enabled=\"false\" />\n          <object-type name=\"CLUSTER\" enabled=\"false\" />\n          <object-type name=\"DBLINK\" enabled=\"true\" />\n        </lookup-objects>\n        <force-database-load value=\"false\" />\n        <prompt-connection-selection value=\"true\" />\n        <prompt-schema-selection value=\"true\" />\n      </lookup-filters>\n    </navigation-settings>\n    <dataset-grid-settings>\n      <general>\n        <enable-zooming value=\"true\" />\n        <enable-column-tooltip value=\"true\" />\n      </general>\n      <sorting>\n        <nulls-first value=\"true\" />\n        <max-sorting-columns value=\"4\" />\n      </sorting>\n      <audit-columns>\n        <column-names value=\"\" />\n        <visible value=\"true\" />\n        <editable value=\"false\" />\n      </audit-columns>\n    </dataset-grid-settings>\n    <dataset-editor-settings>\n      <text-editor-popup>\n        <active value=\"false\" />\n        <active-if-empty value=\"false\" />\n        <data-length-threshold value=\"100\" />\n        <popup-delay value=\"1000\" />\n      </text-editor-popup>\n      <values-actions-popup>\n        <show-popup-button value=\"true\" />\n        <element-count-threshold value=\"1000\" />\n        <data-length-threshold value=\"250\" />\n      </values-actions-popup>\n      <general>\n        <fetch-block-size value=\"100\" />\n        <fetch-timeout value=\"30\" />\n        <trim-whitespaces value=\"true\" />\n        <convert-empty-strings-to-null value=\"true\" />\n        <select-content-on-cell-edit value=\"true\" />\n        <large-value-preview-active value=\"true\" />\n      </general>\n      <filters>\n        <prompt-filter-dialog value=\"true\" />\n        <default-filter-type value=\"BASIC\" />\n      </filters>\n      <qualified-text-editor text-length-threshold=\"300\">\n        <content-types>\n          <content-type name=\"Text\" enabled=\"true\" />\n          <content-type name=\"Properties\" enabled=\"true\" />\n          <content-type name=\"XML\" enabled=\"true\" />\n          <content-type name=\"DTD\" enabled=\"true\" />\n          <content-type name=\"HTML\" enabled=\"true\" />\n          <content-type name=\"XHTML\" enabled=\"true\" />\n          <content-type name=\"Java\" enabled=\"true\" />\n          <content-type name=\"SQL\" enabled=\"true\" />\n          <content-type name=\"PL/SQL\" enabled=\"true\" />\n          <content-type name=\"JSON\" enabled=\"true\" />\n          <content-type name=\"JSON5\" enabled=\"true\" />\n          <content-type name=\"Groovy\" enabled=\"true\" />\n          <content-type name=\"AIDL\" enabled=\"true\" />\n          <content-type name=\"YAML\" enabled=\"true\" />\n          <content-type name=\"Manifest\" enabled=\"true\" />\n        </content-types>\n      </qualified-text-editor>\n      <record-navigation>\n        <navigation-target value=\"VIEWER\" />\n      </record-navigation>\n    </dataset-editor-settings>\n    <code-editor-settings>\n      <general>\n        <show-object-navigation-gutter value=\"false\" />\n        <show-spec-declaration-navigation-gutter value=\"true\" />\n        <enable-spellchecking value=\"true\" />\n        <enable-reference-spellchecking value=\"false\" />\n      </general>\n      <confirmations>\n        <save-changes value=\"false\" />\n        <revert-changes value=\"true\" />\n        <exit-on-changes value=\"ASK\" />\n      </confirmations>\n    </code-editor-settings>\n    <code-completion-settings>\n      <filters>\n        <basic-filter>\n          <filter-element type=\"RESERVED_WORD\" id=\"keyword\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"function\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"parameter\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"datatype\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"exception\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"schema\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"role\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"user\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"privilege\" selected=\"true\" />\n          <user-schema>\n            <filter-element type=\"OBJECT\" id=\"table\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"materialized view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"index\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"constraint\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"trigger\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"synonym\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"sequence\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"procedure\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"function\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"package\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"type\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dimension\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"cluster\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dblink\" selected=\"true\" />\n          </user-schema>\n          <public-schema>\n            <filter-element type=\"OBJECT\" id=\"table\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"view\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"materialized view\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"index\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"constraint\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"trigger\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"synonym\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"sequence\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"procedure\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"function\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"package\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"type\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"dimension\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"cluster\" selected=\"false\" />\n            <filter-element type=\"OBJECT\" id=\"dblink\" selected=\"false\" />\n          </public-schema>\n          <any-schema>\n            <filter-element type=\"OBJECT\" id=\"table\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"materialized view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"index\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"constraint\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"trigger\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"synonym\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"sequence\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"procedure\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"function\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"package\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"type\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dimension\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"cluster\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dblink\" selected=\"true\" />\n          </any-schema>\n        </basic-filter>\n        <extended-filter>\n          <filter-element type=\"RESERVED_WORD\" id=\"keyword\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"function\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"parameter\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"datatype\" selected=\"true\" />\n          <filter-element type=\"RESERVED_WORD\" id=\"exception\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"schema\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"user\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"role\" selected=\"true\" />\n          <filter-element type=\"OBJECT\" id=\"privilege\" selected=\"true\" />\n          <user-schema>\n            <filter-element type=\"OBJECT\" id=\"table\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"materialized view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"index\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"constraint\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"trigger\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"synonym\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"sequence\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"procedure\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"function\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"package\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"type\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dimension\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"cluster\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dblink\" selected=\"true\" />\n          </user-schema>\n          <public-schema>\n            <filter-element type=\"OBJECT\" id=\"table\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"materialized view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"index\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"constraint\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"trigger\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"synonym\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"sequence\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"procedure\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"function\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"package\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"type\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dimension\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"cluster\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dblink\" selected=\"true\" />\n          </public-schema>\n          <any-schema>\n            <filter-element type=\"OBJECT\" id=\"table\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"materialized view\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"index\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"constraint\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"trigger\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"synonym\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"sequence\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"procedure\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"function\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"package\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"type\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dimension\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"cluster\" selected=\"true\" />\n            <filter-element type=\"OBJECT\" id=\"dblink\" selected=\"true\" />\n          </any-schema>\n        </extended-filter>\n      </filters>\n      <sorting enabled=\"true\">\n        <sorting-element type=\"RESERVED_WORD\" id=\"keyword\" />\n        <sorting-element type=\"RESERVED_WORD\" id=\"datatype\" />\n        <sorting-element type=\"OBJECT\" id=\"column\" />\n        <sorting-element type=\"OBJECT\" id=\"table\" />\n        <sorting-element type=\"OBJECT\" id=\"view\" />\n        <sorting-element type=\"OBJECT\" id=\"materialized view\" />\n        <sorting-element type=\"OBJECT\" id=\"index\" />\n        <sorting-element type=\"OBJECT\" id=\"constraint\" />\n        <sorting-element type=\"OBJECT\" id=\"trigger\" />\n        <sorting-element type=\"OBJECT\" id=\"synonym\" />\n        <sorting-element type=\"OBJECT\" id=\"sequence\" />\n        <sorting-element type=\"OBJECT\" id=\"procedure\" />\n        <sorting-element type=\"OBJECT\" id=\"function\" />\n        <sorting-element type=\"OBJECT\" id=\"package\" />\n        <sorting-element type=\"OBJECT\" id=\"type\" />\n        <sorting-element type=\"OBJECT\" id=\"dimension\" />\n        <sorting-element type=\"OBJECT\" id=\"cluster\" />\n        <sorting-element type=\"OBJECT\" id=\"dblink\" />\n        <sorting-element type=\"OBJECT\" id=\"schema\" />\n        <sorting-element type=\"OBJECT\" id=\"role\" />\n        <sorting-element type=\"OBJECT\" id=\"user\" />\n        <sorting-element type=\"RESERVED_WORD\" id=\"function\" />\n        <sorting-element type=\"RESERVED_WORD\" id=\"parameter\" />\n      </sorting>\n      <format>\n        <enforce-code-style-case value=\"true\" />\n      </format>\n    </code-completion-settings>\n    <execution-engine-settings>\n      <statement-execution>\n        <fetch-block-size value=\"100\" />\n        <execution-timeout value=\"20\" />\n        <debug-execution-timeout value=\"600\" />\n        <focus-result value=\"false\" />\n        <prompt-execution value=\"false\" />\n      </statement-execution>\n      <script-execution>\n        <command-line-interfaces />\n        <execution-timeout value=\"300\" />\n      </script-execution>\n      <method-execution>\n        <execution-timeout value=\"30\" />\n        <debug-execution-timeout value=\"600\" />\n        <parameter-history-size value=\"10\" />\n      </method-execution>\n    </execution-engine-settings>\n    <operation-settings>\n      <transactions>\n        <uncommitted-changes>\n          <on-project-close value=\"ASK\" />\n          <on-disconnect value=\"ASK\" />\n          <on-autocommit-toggle value=\"ASK\" />\n        </uncommitted-changes>\n        <multiple-uncommitted-changes>\n          <on-commit value=\"ASK\" />\n          <on-rollback value=\"ASK\" />\n        </multiple-uncommitted-changes>\n      </transactions>\n      <session-browser>\n        <disconnect-session value=\"ASK\" />\n        <kill-session value=\"ASK\" />\n        <reload-on-filter-change value=\"false\" />\n      </session-browser>\n      <compiler>\n        <compile-type value=\"KEEP\" />\n        <compile-dependencies value=\"ASK\" />\n        <always-show-controls value=\"false\" />\n      </compiler>\n    </operation-settings>\n    <ddl-file-settings>\n      <extensions>\n        <mapping file-type-id=\"VIEW\" extensions=\"vw\" />\n        <mapping file-type-id=\"TRIGGER\" extensions=\"trg\" />\n        <mapping file-type-id=\"PROCEDURE\" extensions=\"prc\" />\n        <mapping file-type-id=\"FUNCTION\" extensions=\"fnc\" />\n        <mapping file-type-id=\"PACKAGE\" extensions=\"pkg\" />\n        <mapping file-type-id=\"PACKAGE_SPEC\" extensions=\"pks\" />\n        <mapping file-type-id=\"PACKAGE_BODY\" extensions=\"pkb\" />\n        <mapping file-type-id=\"TYPE\" extensions=\"tpe\" />\n        <mapping file-type-id=\"TYPE_SPEC\" extensions=\"tps\" />\n        <mapping file-type-id=\"TYPE_BODY\" extensions=\"tpb\" />\n      </extensions>\n      <general>\n        <lookup-ddl-files value=\"true\" />\n        <create-ddl-files value=\"false\" />\n        <synchronize-ddl-files value=\"true\" />\n        <use-qualified-names value=\"false\" />\n        <make-scripts-rerunnable value=\"true\" />\n      </general>\n    </ddl-file-settings>\n    <general-settings>\n      <regional-settings>\n        <date-format value=\"MEDIUM\" />\n        <number-format value=\"UNGROUPED\" />\n        <locale value=\"SYSTEM_DEFAULT\" />\n        <use-custom-formats value=\"false\" />\n      </regional-settings>\n      <environment>\n        <environment-types>\n          <environment-type id=\"development\" name=\"Development\" description=\"Development environment\" color=\"-2430209/-12296320\" readonly-code=\"false\" readonly-data=\"false\" />\n          <environment-type id=\"integration\" name=\"Integration\" description=\"Integration environment\" color=\"-2621494/-12163514\" readonly-code=\"true\" readonly-data=\"false\" />\n          <environment-type id=\"production\" name=\"Production\" description=\"Productive environment\" color=\"-11574/-10271420\" readonly-code=\"true\" readonly-data=\"true\" />\n          <environment-type id=\"other\" name=\"Other\" description=\"\" color=\"-1576/-10724543\" readonly-code=\"false\" readonly-data=\"false\" />\n        </environment-types>\n        <visibility-settings>\n          <connection-tabs value=\"true\" />\n          <dialog-headers value=\"true\" />\n          <object-editor-tabs value=\"true\" />\n          <script-editor-tabs value=\"false\" />\n          <execution-result-tabs value=\"true\" />\n        </visibility-settings>\n      </environment>\n    </general-settings>\n  </component>\n  <component name=\"DBNavigator.Project.StatementExecutionManager\">\n    <execution-variables />\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    <value>\n      <entry key=\"app\">\n        <State />\n      </entry>\n    </value>\n  </component>\n</project>"
  },
  {
    "path": ".idea/dictionaries/ShihCheeng.xml",
    "content": "<component name=\"ProjectDictionaryState\">\n  <dictionary name=\"ShihCheeng\" />\n</component>"
  },
  {
    "path": ".idea/fastRequest/fastRequestCollection.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"fastRequestCollection\">\n    <option name=\"detail\">\n      <CollectionDetail>\n        <option name=\"childList\">\n          <list>\n            <CollectionDetail>\n              <option name=\"groupId\" value=\"1\" />\n              <option name=\"id\" value=\"1\" />\n              <option name=\"name\" value=\"Default Group\" />\n              <option name=\"type\" value=\"1\" />\n            </CollectionDetail>\n          </list>\n        </option>\n        <option name=\"groupId\" value=\"-1\" />\n        <option name=\"id\" value=\"0\" />\n        <option name=\"name\" value=\"Root\" />\n        <option name=\"type\" value=\"1\" />\n      </CollectionDetail>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/fastRequest/fastRequestCurrentProjectLocalConfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"fastRequestCurrentProjectLocalConfig\">\n    <option name=\"domain\" value=\"api.co\" />\n    <option name=\"enableEnv\" value=\"App\" />\n    <option name=\"enableProject\" value=\"App\" />\n    <option name=\"initFlag\" value=\"1\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/fastRequest/fastRequestHistoryConfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"fastRequestHistoryConfig\">\n    <option name=\"historyList\">\n      <list>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"bodyKeyValueListJson\" value=\"{&quot;term&quot;:&quot;我&quot;, &quot;num&quot;:10}\" />\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"methodType\" value=\"POST\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;device&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;platform&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;web&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"device=pc&#10;&amp;platform=web\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug?device=%70%63&amp;platform=%77%65%62&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;    Content-Length: 24&#13;&#10;    Content-Type: application/json;charset=UTF-8&#13;&#10;Request Body: &#13;&#10;    {&quot;term&quot;:&quot;我&quot;, &quot;num&quot;:10}&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:0,&quot;msg&quot;:&quot;&quot;,&quot;data&quot;:[&quot;我和我对家&quot;,&quot;我行让我来&quot;,&quot;我家侯爷不宠我&quot;,&quot;我叫我同桌打你&quot;,&quot;我还小&quot;,&quot;我是女帝我好南&quot;,&quot;总裁偏要宠我宠我&quot;,&quot;我和我的四个伴舞&quot;,&quot;理我一下&quot;,&quot;我缭不动&quot;]}\" />\n          <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"bodyKeyValueListJson\" value=\"{&quot;term&quot;:&quot;我&quot;, &quot;num&quot;:10}\" />\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"methodType\" value=\"POST\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;device&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;platform&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;web&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"device=pc&#10;&amp;platform=web\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug?device=%70%63&amp;platform=%77%65%62&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://manga.bilibili.com/?from=bill_top_mnav&amp;spm_id_from=333.1007.0.0&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;    Content-Length: 24&#13;&#10;    Content-Type: application/json;charset=UTF-8&#13;&#10;Request Body: &#13;&#10;    {&quot;term&quot;:&quot;我&quot;, &quot;num&quot;:10}&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:0,&quot;msg&quot;:&quot;&quot;,&quot;data&quot;:[&quot;我和我对家&quot;,&quot;我行让我来&quot;,&quot;我家侯爷不宠我&quot;,&quot;我叫我同桌打你&quot;,&quot;我还小&quot;,&quot;我是女帝我好南&quot;,&quot;总裁偏要宠我宠我&quot;,&quot;我和我的四个伴舞&quot;,&quot;理我一下&quot;,&quot;我缭不动&quot;]}\" />\n          <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"bodyKeyValueListJson\" value=\"{&quot;term&quot;:&quot;我&quot;, &quot;num&quot;:20}\" />\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"methodType\" value=\"POST\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;device&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;platform&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;web&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"device=pc&#10;&amp;platform=web\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug?device=%70%63&amp;platform=%77%65%62&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://manga.bilibili.com/?from=bill_top_mnav&amp;spm_id_from=333.1007.0.0&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;    Content-Length: 24&#13;&#10;    Content-Type: application/json;charset=UTF-8&#13;&#10;Request Body: &#13;&#10;    {&quot;term&quot;:&quot;我&quot;, &quot;num&quot;:20}&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:0,&quot;msg&quot;:&quot;&quot;,&quot;data&quot;:[&quot;我和我对家&quot;,&quot;我行让我来&quot;,&quot;我叫我同桌打你&quot;,&quot;我家侯爷不宠我&quot;,&quot;我还小&quot;,&quot;我是女帝我好南&quot;,&quot;总裁偏要宠我宠我&quot;,&quot;我和我的四个伴舞&quot;,&quot;我是剑仙&quot;,&quot;我是人才&quot;,&quot;我的西施&quot;,&quot;我有病啊&quot;,&quot;我缭不动&quot;,&quot;理我一下&quot;,&quot;我&quot;,&quot;我家驸马竟要和我炒CP&quot;,&quot;我和我的理想型嗝屁了！&quot;,&quot;我为苍生&quot;,&quot;臣服于我&quot;,&quot;你我之间&quot;]}\" />\n          <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"bodyKeyValueListJson\" value=\"{&quot;term&quot;:&quot;我的无&quot;,&quot;num&quot;:20}\" />\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"methodType\" value=\"POST\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;device&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;platform&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;web&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"device=pc&#10;&amp;platform=web\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug?device=%70%63&amp;platform=%77%65%62&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://manga.bilibili.com/?from=bill_top_mnav&amp;spm_id_from=333.1007.0.0&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;    Content-Length: 29&#13;&#10;    Content-Type: application/json;charset=UTF-8&#13;&#10;Request Body: &#13;&#10;    {&quot;term&quot;:&quot;我的无&quot;,&quot;num&quot;:20}&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:0,&quot;msg&quot;:&quot;&quot;,&quot;data&quot;:[&quot;我的无间女友&quot;]}\" />\n          <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"400\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"methodType\" value=\"POST\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;device&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;platform&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;web&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"device=pc&#10;&amp;platform=web\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug?device=%70%63&amp;platform=%77%65%62&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://manga.bilibili.com/?from=bill_top_mnav&amp;spm_id_from=333.1007.0.0&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:&quot;invalid_argument&quot;,&quot;msg&quot;:&quot;term, num not empty&quot;,&quot;meta&quot;:{&quot;argument&quot;:&quot;term, num&quot;}}\" />\n          <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"400\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"methodType\" value=\"POST\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;device&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;platform&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;web&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"device=pc&#10;&amp;platform=web\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug?device=%70%63&amp;platform=%77%65%62&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:&quot;invalid_argument&quot;,&quot;msg&quot;:&quot;origin www.baidu.com&quot;,&quot;meta&quot;:{&quot;argument&quot;:&quot;origin&quot;}}\" />\n          <option name=\"url\" value=\"https://manga.bilibili.com/twirp/comic.v1.Comic/SearchSug\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;东&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"wd=东\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=%E4%B8%9C&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"window.baidu.sug({q:&quot;东&quot;,p:false,s:[&quot;东方财富网&quot;,&quot;东莞&quot;,&quot;东南大学&quot;,&quot;东北警察故事2&quot;,&quot;东的笔顺&quot;,&quot;东北三省是哪三省&quot;,&quot;东施效颦什么意思&quot;,&quot;东野圭吾&quot;,&quot;东宫&quot;,&quot;东京喰种&quot;]});\" />\n          <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;wu&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"wd=wu\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=%77%75&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"window.baidu.sug({q:&quot;wu&quot;,p:false,s:[&quot;悟饭游戏厅&quot;,&quot;武汉天气&quot;,&quot;梧州学院&quot;,&quot;五岳是指哪五座山?&quot;,&quot;武汉大学&quot;,&quot;吴越&quot;,&quot;无畏契约&quot;,&quot;武神主宰&quot;,&quot;吴磊&quot;,&quot;无锡学院&quot;]});\" />\n          <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;?wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;wu&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"?wd=wu\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su??wd=%77%75&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"window.baidu.sug({q:&quot;&quot;,p:,s:[]});\" />\n          <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;?wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;穷&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"?wd=穷\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su??wd=%E7%A9%B7&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"window.baidu.sug({q:&quot;&quot;,p:,s:[]});\" />\n          <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=%E6%88%91%E7%9A%84\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[]\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=%E6%88%91%E7%9A%84&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"window.baidu.sug({q:&quot;我的&quot;,p:false,s:[&quot;我的世界下载&quot;,&quot;我的人间烟火 电视剧&quot;,&quot;我的人间烟火电视剧免费观看&quot;,&quot;我的世界java版下载&quot;,&quot;我的世界1.20国际版下载&quot;,&quot;我的世界国际版下载&quot;,&quot;我的世界1.19基岩版下载&quot;,&quot;我的徒弟都是大反派&quot;,&quot;我的26岁女房客小说&quot;,&quot;我的世界网易版&quot;]});\" />\n          <option name=\"url\" value=\"https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=%E6%88%91%E7%9A%84\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=san&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[]\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=san&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"jQuery1102007482779509809379_1688713427026({&quot;q&quot;:&quot;san&quot;,&quot;p&quot;:false,&quot;g&quot;:[{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_1&quot;,&quot;q&quot;:&quot;三伏天&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_2&quot;,&quot;q&quot;:&quot;三d开奖历史开奖结果&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_3&quot;,&quot;q&quot;:&quot;三字经&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_4&quot;,&quot;q&quot;:&quot;三国志战略版&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_5&quot;,&quot;q&quot;:&quot;三衢道中&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_6&quot;,&quot;q&quot;:&quot;三峡&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_7&quot;,&quot;q&quot;:&quot;桑葚&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_8&quot;,&quot;q&quot;:&quot;三伏天是几月几号2023&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_9&quot;,&quot;q&quot;:&quot;sandwich&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_10&quot;,&quot;q&quot;:&quot;三分野&quot;}],&quot;slid&quot;:&quot;10068427565551&quot;,&quot;queryid&quot;:&quot;0x13209283d0c69ef&quot;})\" />\n          <option name=\"url\" value=\"https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=san&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[]\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"jQuery1102007482779509809379_1688713427026({&quot;q&quot;:&quot;er&quot;,&quot;p&quot;:false,&quot;g&quot;:[{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_1&quot;,&quot;q&quot;:&quot;erp&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_2&quot;,&quot;q&quot;:&quot;二阳有哪些症状&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_3&quot;,&quot;q&quot;:&quot;erp企业管理系统软件&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_4&quot;,&quot;q&quot;:&quot;erp是什么意思&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_5&quot;,&quot;q&quot;:&quot;erp系统&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_6&quot;,&quot;q&quot;:&quot;eraser&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_7&quot;,&quot;q&quot;:&quot;erp系统主要干什么的&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_8&quot;,&quot;q&quot;:&quot;二十四节气&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_9&quot;,&quot;q&quot;:&quot;二哈和他的白猫师尊&quot;},{&quot;type&quot;:&quot;sug&quot;,&quot;sa&quot;:&quot;s_10&quot;,&quot;q&quot;:&quot;耳石症&quot;}],&quot;slid&quot;:&quot;167481851433744&quot;,&quot;queryid&quot;:&quot;0x959852e842d310&quot;})\" />\n          <option name=\"url\" value=\"https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pre&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;p&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;3&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;ie&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;utf-8&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;json&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;prod&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;from&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc_web&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;sugsid&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;er&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;req&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;csor&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pwd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;new&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;cb&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;jQuery1102007482779509809379_1688713427026&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;_&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1688713427034&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"pre=1&#10;&amp;p=3&#10;&amp;ie=utf-8&#10;&amp;json=1&#10;&amp;prod=pc&#10;&amp;from=pc_web&#10;&amp;sugsid=1&#10;&amp;wd=er&#10;&amp;req=2&#10;&amp;csor=2&#10;&amp;pwd=new&#10;&amp;cb=jQuery1102007482779509809379_1688713427026&#10;&amp;_=1688713427034\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034?p=%33&amp;pre=%31&amp;prod=%70%63&amp;sugsid=%31&amp;json=%31&amp;from=%70%63%5F%77%65%62&amp;pwd=%6E%65%77&amp;ie=%75%74%66%2D%38&amp;csor=%32&amp;wd=%65%72&amp;_=%31%36%38%38%37%31%33%34%32%37%30%33%34&amp;cb=%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36&amp;req=%32&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36({&quot;q&quot;:&quot;er&quot;})\" />\n          <option name=\"url\" value=\"https://www.baidu.com/sugrec?pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pre&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;p&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;3&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;ie&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;utf-8&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;json&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;prod&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;from&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc_web&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;sugsid&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;er&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;req&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;csor&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pwd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;new&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;cb&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;jQuery1102007482779509809379_1688713427026&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;_&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1688713427034&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"pre=1&#10;&amp;p=3&#10;&amp;ie=utf-8&#10;&amp;json=1&#10;&amp;prod=pc&#10;&amp;from=pc_web&#10;&amp;sugsid=1&#10;&amp;wd=er&#10;&amp;req=2&#10;&amp;csor=2&#10;&amp;pwd=new&#10;&amp;cb=jQuery1102007482779509809379_1688713427026&#10;&amp;_=1688713427034\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://www.baidu.com/sugrec?p=%33&amp;pre=%31&amp;prod=%70%63&amp;sugsid=%31&amp;json=%31&amp;from=%70%63%5F%77%65%62&amp;pwd=%6E%65%77&amp;ie=%75%74%66%2D%38&amp;csor=%32&amp;wd=%65%72&amp;_=%31%36%38%38%37%31%33%34%32%37%30%33%34&amp;cb=%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36&amp;req=%32&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36({&quot;q&quot;:&quot;er&quot;})\" />\n          <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pre&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;p&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;3&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;ie&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;utf-8&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;json&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;prod&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;from&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc_web&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;sugsid&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;er&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;req&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;csor&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pwd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;new&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;cb&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;jQuery1102007482779509809379_1688713427026&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;_&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1688713427034&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"pre=1&#10;&amp;p=3&#10;&amp;ie=utf-8&#10;&amp;json=1&#10;&amp;prod=pc&#10;&amp;from=pc_web&#10;&amp;sugsid=1&#10;&amp;wd=er&#10;&amp;req=2&#10;&amp;csor=2&#10;&amp;pwd=new&#10;&amp;cb=jQuery1102007482779509809379_1688713427026&#10;&amp;_=1688713427034\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://www.baidu.com/sugrec?p=%33&amp;pre=%31&amp;prod=%70%63&amp;sugsid=%31&amp;json=%31&amp;from=%70%63%5F%77%65%62&amp;pwd=%6E%65%77&amp;ie=%75%74%66%2D%38&amp;csor=%32&amp;wd=%65%72&amp;_=%31%36%38%38%37%31%33%34%32%37%30%33%34&amp;cb=%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36&amp;req=%32&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36({&quot;q&quot;:&quot;er&quot;})\" />\n          <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pre&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;p&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;3&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;ie&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;utf-8&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;json&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;prod&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;from&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc_web&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;sugsid&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;er&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;req&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;csor&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pwd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;new&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;cb&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;jQuery1102007482779509809379_1688713427026&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;_&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1688713427034&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://www.baidu.com/sugrec?p=%33&amp;pre=%31&amp;prod=%70%63&amp;sugsid=%33%36%35%35%31%2C%33%39%30%32%36%2C%33%39%30%32%34%2C%33%38%39%34%33%2C%33%38%38%36%30%2C%33%38%39%35%38%2C%33%38%39%35%36%2C%33%39%30%30%39%2C%33%38%39%36%37%2C%33%38%39%31%38%2C%33%38%39%37%32%2C%33%38%38%32%30%2C%33%38%36%33%36%2C%32%36%33%35%30%2C%33%39%30%34%31&amp;json=%31&amp;from=%70%63%5F%77%65%62&amp;pwd=%6E%65%77&amp;ie=%75%74%66%2D%38&amp;csor=%32&amp;wd=%65%72&amp;_=%31%36%38%38%37%31%33%34%32%37%30%33%34&amp;cb=%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36&amp;req=%32&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Referer: https://www.baidu.com/&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36({&quot;q&quot;:&quot;er&quot;})\" />\n          <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pre&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;p&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;3&quot;},{&quot;comment&quot;:&quot;&quot;,&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;ie&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;utf-8&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;json&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;prod&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;from&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;pc_web&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;sugsid&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;wd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;er&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;req&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;csor&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;2&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;pwd&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;new&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;cb&quot;,&quot;type&quot;:&quot;String&quot;,&quot;value&quot;:&quot;jQuery1102007482779509809379_1688713427026&quot;},{&quot;customFlag&quot;:2,&quot;enabled&quot;:true,&quot;key&quot;:&quot;_&quot;,&quot;type&quot;:&quot;Number&quot;,&quot;value&quot;:&quot;1688713427034&quot;}]\" />\n              <option name=\"urlParamsKeyValueListText\" value=\"pre=1&amp;p=3&amp;ie=utf-8&amp;json=1&amp;prod=pc&amp;from=pc_web&amp;sugsid=36551,39026,39024,38943,38860,38958,38956,39009,38967,38918,38972,38820,38636,26350,39041&amp;wd=er&amp;req=2&amp;csor=2&amp;pwd=new&amp;cb=jQuery1102007482779509809379_1688713427026&amp;_=1688713427034\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://www.baidu.com/sugrec?p=%33&amp;pre=%31&amp;prod=%70%63&amp;sugsid=%33%36%35%35%31%2C%33%39%30%32%36%2C%33%39%30%32%34%2C%33%38%39%34%33%2C%33%38%38%36%30%2C%33%38%39%35%38%2C%33%38%39%35%36%2C%33%39%30%30%39%2C%33%38%39%36%37%2C%33%38%39%31%38%2C%33%38%39%37%32%2C%33%38%38%32%30%2C%33%38%36%33%36%2C%32%36%33%35%30%2C%33%39%30%34%31&amp;json=%31&amp;from=%70%63%5F%77%65%62&amp;pwd=%6E%65%77&amp;ie=%75%74%66%2D%38&amp;csor=%32&amp;wd=%65%72&amp;_=%31%36%38%38%37%31%33%34%32%37%30%33%34&amp;cb=%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36&amp;req=%32&#13;&#10;Request Headers: &#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"%6A%51%75%65%72%79%31%31%30%32%30%30%37%34%38%32%37%37%39%35%30%39%38%30%39%33%37%39%5F%31%36%38%38%37%31%33%34%32%37%30%32%36({&quot;q&quot;:&quot;er&quot;})\" />\n          <option name=\"url\" value=\"https://www.baidu.com/sugrec\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://api.copymanga.net/api/v3/comic/wodebingruoxixuegui/chapter2/029fb178-8611-11eb-84af-00163e0ca5bd?platform=3\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[]\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://api.copymanga.net/api/v3/comic/wodebingruoxixuegui/chapter2/029fb178-8611-11eb-84af-00163e0ca5bd?platform=3&#13;&#10;Request Headers: &#13;&#10;    referer: https://www.copymanga.site/&#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;    webp: 0&#13;&#10;    region: 0&#13;&#10;    version: &#13;&#10;    platform: &#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:200,&quot;message&quot;:&quot;请求成功&quot;,&quot;results&quot;:{&quot;show_app&quot;:false,&quot;is_lock&quot;:false,&quot;is_login&quot;:false,&quot;is_mobile_bind&quot;:false,&quot;is_vip&quot;:false,&quot;comic&quot;:{&quot;name&quot;:&quot;我的病弱吸血鬼&quot;,&quot;uuid&quot;:&quot;9dcef9b0-6e06-11eb-894c-00163e0ca5bd&quot;,&quot;path_word&quot;:&quot;wodebingruoxixuegui&quot;,&quot;restrict&quot;:{&quot;value&quot;:0,&quot;display&quot;:&quot;一般向(免費)&quot;}},&quot;chapter&quot;:{&quot;index&quot;:1,&quot;uuid&quot;:&quot;029fb178-8611-11eb-84af-00163e0ca5bd&quot;,&quot;count&quot;:26,&quot;ordered&quot;:20,&quot;size&quot;:48,&quot;name&quot;:&quot;第02话&quot;,&quot;comic_id&quot;:&quot;9dcef9b0-6e06-11eb-894c-00163e0ca5bd&quot;,&quot;comic_path_word&quot;:&quot;wodebingruoxixuegui&quot;,&quot;group_id&quot;:null,&quot;group_path_word&quot;:&quot;default&quot;,&quot;type&quot;:1,&quot;img_type&quot;:2,&quot;news&quot;:&quot;success1&quot;,&quot;datetime_created&quot;:&quot;2021-03-16&quot;,&quot;prev&quot;:&quot;84eed7c8-6e09-11eb-b1c9-00163e0ca5bd&quot;,&quot;next&quot;:&quot;3427d246-9932-11eb-89a9-00163e0ca5bd&quot;,&quot;contents&quot;:[{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501526612/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501563574/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501590487/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501619715/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501646161/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501670549/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501696961/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501724832/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501752452/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501779668/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501809800/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501839272/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501864805/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501892166/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501922003/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501946747/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401501973638/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502000809/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502028320/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502054069/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502082460/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502108195/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502134042/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502161656/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502540097/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502511679/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502352042/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502621456/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502214834/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502457534/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502378207/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502406594/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502819351/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502594905/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502323122/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502270595/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502566071/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502679112/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502485343/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502244521/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502768605/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502648830/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502431993/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502709148/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502737094/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502186427/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502799269/c800x.jpg&quot;},{&quot;url&quot;:&quot;https://hi77-overseas.mangafuna.xyz/wodebingruoxixuegui/c2a8e/16401502295995/c800x.jpg&quot;}],&quot;words&quot;:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,37,36,30,40,25,34,31,32,47,39,29,27,38,42,35,26,45,41,33,43,44,24,46,28],&quot;is_long&quot;:false}}}\" />\n          <option name=\"url\" value=\"https://api.copymanga.net/api/v3/comic/wodebingruoxixuegui/chapter2/029fb178-8611-11eb-84af-00163e0ca5bd?platform=3\" />\n        </ResponseHistory>\n        <ResponseHistory>\n          <option name=\"className\" />\n          <option name=\"code\" value=\"200\" />\n          <option name=\"enableEnv\" value=\"App\" />\n          <option name=\"enableProject\" value=\"App\" />\n          <option name=\"method\" />\n          <option name=\"methodType\" value=\"GET\" />\n          <option name=\"paramGroup\">\n            <ParamGroupCollection>\n              <option name=\"methodDescription\" value=\"New Request\" />\n              <option name=\"multipartKeyValueListJson\" value=\"[]\" />\n              <option name=\"pathParamsKeyValueListJson\" value=\"[]\" />\n              <option name=\"url\" value=\"https://api.copymanga.net/api/v3/search/comic?format=json&amp;limit=21&amp;offset=0&amp;platform=3&amp;q=new\" />\n              <option name=\"urlEncodedKeyValueListJson\" value=\"[]\" />\n              <option name=\"urlParamsKeyValueListJson\" value=\"[]\" />\n            </ParamGroupCollection>\n          </option>\n          <option name=\"requestInfo\" value=\"Request Url: https://api.copymanga.net/api/v3/search/comic?format=json&amp;limit=21&amp;offset=0&amp;platform=3&amp;q=new&#13;&#10;Request Headers: &#13;&#10;    referer: https://www.copymanga.site/&#13;&#10;    Accept: application/json,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&#13;&#10;    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36 Hutool&#13;&#10;    Accept-Encoding: gzip, deflate&#13;&#10;    Accept-Language: zh-CN,zh;q=0.8&#13;&#10;    webp: 0&#13;&#10;    region: 0&#13;&#10;    version: &#13;&#10;    platform: &#13;&#10;Request Body: &#13;&#10;    null&#13;&#10;\" />\n          <option name=\"response\" value=\"{&quot;code&quot;:200,&quot;message&quot;:&quot;请求成功&quot;,&quot;results&quot;:{&quot;list&quot;:[{&quot;name&quot;:&quot;New LovePlus&quot;,&quot;alias&quot;:&quot;New LovePlus,New LovePlus&quot;,&quot;path_word&quot;:&quot;newloveplus&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/newloveplus/cover/1651091182.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;濑尾公治&quot;,&quot;alias&quot;:&quot;濑尾公治&quot;,&quot;path_word&quot;:&quot;lwgz&quot;}],&quot;popular&quot;:1742},{&quot;name&quot;:&quot;New Game!&quot;,&quot;alias&quot;:&quot;NewGame!,New Game!,New Game!&quot;,&quot;path_word&quot;:&quot;newgame&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/newgame/cover/1651387307.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;得能正太郎&quot;,&quot;alias&quot;:&quot;得能正太郎&quot;,&quot;path_word&quot;:&quot;denengzhengtailang&quot;}],&quot;popular&quot;:229182},{&quot;name&quot;:&quot;The New Gate&quot;,&quot;alias&quot;:&quot;thenewgate,The New Gate,The New Gate&quot;,&quot;path_word&quot;:&quot;thenewgate&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/thenewgate/cover/1651011915.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;风波しのぎ&quot;,&quot;alias&quot;:&quot;风波しのぎ&quot;,&quot;path_word&quot;:&quot;fengbo&quot;},{&quot;name&quot;:&quot;三轮ヨツユキ&quot;,&quot;alias&quot;:&quot;三轮ヨツユキ&quot;,&quot;path_word&quot;:&quot;sanl&quot;}],&quot;popular&quot;:341852},{&quot;name&quot;:&quot;Welcome To New Dawan&quot;,&quot;alias&quot;:&quot;Welcome New Dawan,Welcome To New Dawan,Welcome To New Dawan&quot;,&quot;path_word&quot;:&quot;welcomenewdawan&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/welcomenewdawan/cover/1651138649.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;ZUMMENG&quot;,&quot;alias&quot;:null,&quot;path_word&quot;:&quot;zummeng&quot;}],&quot;popular&quot;:2476},{&quot;name&quot;:&quot;Happy New Year&quot;,&quot;alias&quot;:&quot;Happy New Year,Happy New Year&quot;,&quot;path_word&quot;:&quot;happynewyear&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/happynewyear/cover/1651106603.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;むつき润&quot;,&quot;alias&quot;:&quot;むつき润&quot;,&quot;path_word&quot;:&quot;mucikirun&quot;}],&quot;popular&quot;:574},{&quot;name&quot;:&quot;THE KING OF FIGHTERS～A NEW BEGINNING～&quot;,&quot;alias&quot;:&quot;THE KING OF FIGHTERS A NEW BEGINNING,KOF拳皇,THE KING OF FIGHTERS～A NEW BEGINNING～,THE KING OF FIGHTERS～A NEW BEGINNING～&quot;,&quot;path_word&quot;:&quot;thekingoffightersanewbeginning&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/thekingoffightersanewbeginning/cover/1651049003.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;あずま京太郎&quot;,&quot;alias&quot;:&quot;あずま京太郎&quot;,&quot;path_word&quot;:&quot;azumajingtailang&quot;}],&quot;popular&quot;:60809},{&quot;name&quot;:&quot;Brand-new day&quot;,&quot;alias&quot;:&quot;Brand-new day,Brand-new day&quot;,&quot;path_word&quot;:&quot;brandnewday&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/brandnewday/cover/1651106343.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;武者プルーン&quot;,&quot;alias&quot;:&quot;武者プルーン&quot;,&quot;path_word&quot;:&quot;wuzhe&quot;}],&quot;popular&quot;:446},{&quot;name&quot;:&quot;天籟人偶 New Order&quot;,&quot;alias&quot;:&quot;天籁人偶 New Order&quot;,&quot;path_word&quot;:&quot;tianlairenouneworder&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/tianlairenouneworder/cover/1657388243.jpg.328x422.jpg&quot;,&quot;img_type&quot;:1,&quot;author&quot;:[{&quot;name&quot;:&quot;浅见百合子&quot;,&quot;alias&quot;:&quot;浅见百合子&quot;,&quot;path_word&quot;:&quot;qianjian&quot;}],&quot;popular&quot;:2734},{&quot;name&quot;:&quot;THE IDOLM@STER MILLION LIVE! Brand New Song&quot;,&quot;alias&quot;:&quot;偶像大师Brand New Song,THE IDOLM@STER MILLION LIVE! Brand New Song,THE IDOLM@STER MILLION LIVE! Brand New Song&quot;,&quot;path_word&quot;:&quot;theidolmstermillionlivebrandnewsong&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/theidolmstermillionlivebrandnewsong/cover/1652867951.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;IMA&quot;,&quot;alias&quot;:&quot;IMA&quot;,&quot;path_word&quot;:&quot;ima&quot;}],&quot;popular&quot;:8227},{&quot;name&quot;:&quot;HAPPY NEW LOVE&quot;,&quot;alias&quot;:null,&quot;path_word&quot;:&quot;happynewlove&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/happynewlove/cover/1673852135.jpg.328x422.jpg&quot;,&quot;img_type&quot;:1,&quot;author&quot;:[{&quot;name&quot;:&quot;春兔あや&quot;,&quot;alias&quot;:null,&quot;path_word&quot;:&quot;chuntushasha&quot;}],&quot;popular&quot;:4662},{&quot;name&quot;:&quot;ALL-NEW Marvel Now原點v1&quot;,&quot;alias&quot;:&quot;All-New Marvel NOW! Point One Vol.1,ALL-NEW Marvel Now原點v1,ALL-NEW Marvel Now原点v1&quot;,&quot;path_word&quot;:&quot;pointonemarvelnow&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/pointonemarvelnow/cover/1650989197.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;Marvel Comics&quot;,&quot;alias&quot;:&quot;Marvel Comics&quot;,&quot;path_word&quot;:&quot;marvel&quot;}],&quot;popular&quot;:1861},{&quot;name&quot;:&quot;不自重前勇者強大又輕鬆的NEW GAME&quot;,&quot;alias&quot;:&quot;不自重前勇者强大又轻松的NEW GAME，我曾經是個勇者,我曾经是个勇者&quot;,&quot;path_word&quot;:&quot;buzizhongqianyongzheqiangdayouqingsongdenewgame&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/buzizhongqianyongzheqiangdayouqingsongdenewgame/cover/1666322838.jpg.328x422.jpg&quot;,&quot;img_type&quot;:1,&quot;author&quot;:[{&quot;name&quot;:&quot;ていやん&quot;,&quot;alias&quot;:null,&quot;path_word&quot;:&quot;teiyan&quot;}],&quot;popular&quot;:2541098},{&quot;name&quot;:&quot;(C100) [M .M (針川ミア)] A NEW LOOK (ラブライブ!虹ヶ咲学園スクールアイドル同好会)&quot;,&quot;alias&quot;:&quot;(C100)A NEW LOOK,lovelive同人&quot;,&quot;path_word&quot;:&quot;anwelook&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/anwelook/cover/1674820011.jpg.328x422.jpg&quot;,&quot;img_type&quot;:1,&quot;author&quot;:[{&quot;name&quot;:&quot;針川ミア&quot;,&quot;alias&quot;:&quot;Harikawa Mia,针川ミア,M .M (針川ミア)&quot;,&quot;path_word&quot;:&quot;HarikawaMia&quot;}],&quot;popular&quot;:2617},{&quot;name&quot;:&quot;新52火風暴&quot;,&quot;alias&quot;:&quot;new52 Firestorm,新52火風暴,新52火风暴&quot;,&quot;path_word&quot;:&quot;x52huofengbao&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/x52huofengbao/cover/1650974471.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;DC Comics&quot;,&quot;alias&quot;:&quot;DC Comics&quot;,&quot;path_word&quot;:&quot;dccomics&quot;}],&quot;popular&quot;:3807},{&quot;name&quot;:&quot;全新X因子v1&quot;,&quot;alias&quot;:&quot;全新X因子ALL-NEW Marvel NOW!,全新X因子v1,全新X因子v1&quot;,&quot;path_word&quot;:&quot;quanxinxyinziallnewmarvelnow&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/quanxinxyinziallnewmarvelnow/cover/1651014096.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;Marvel Comics&quot;,&quot;alias&quot;:&quot;Marvel Comics&quot;,&quot;path_word&quot;:&quot;marvel&quot;}],&quot;popular&quot;:3584},{&quot;name&quot;:&quot;Sex新常態&quot;,&quot;alias&quot;:&quot;New Normal Sex,Sex新常態,Sex新常态&quot;,&quot;path_word&quot;:&quot;sexxinchangtai&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/sexxinchangtai/cover/1651186474.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;まんだ林檎&quot;,&quot;alias&quot;:null,&quot;path_word&quot;:&quot;mandalq&quot;}],&quot;popular&quot;:31517},{&quot;name&quot;:&quot;不擅長和人說話…！&quot;,&quot;alias&quot;:&quot;不擅长和人说话…！,NEW GAME同人&quot;,&quot;path_word&quot;:&quot;bushanchangherenshuohua&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/bushanchangherenshuohua/cover/1684584804.jpg.328x422.jpg&quot;,&quot;img_type&quot;:1,&quot;author&quot;:[{&quot;name&quot;:&quot;いれぅ&quot;,&quot;alias&quot;:null,&quot;path_word&quot;:&quot;irexu&quot;}],&quot;popular&quot;:551},{&quot;name&quot;:&quot;全新侵襲組v1&quot;,&quot;alias&quot;:&quot;All-New Invaders Vol.1,全新侵袭组ALL-NEW Marvel Now,全新侵襲組v1,全新侵袭组v1&quot;,&quot;path_word&quot;:&quot;quanxinqinxizu&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/quanxinqinxizu/cover/1650987300.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;Marvel Comics&quot;,&quot;alias&quot;:&quot;Marvel Comics&quot;,&quot;path_word&quot;:&quot;marvel&quot;}],&quot;popular&quot;:3211},{&quot;name&quot;:&quot;新52閃電俠&quot;,&quot;alias&quot;:&quot;NEW 52 The Flash,新52閃電俠,新52闪电侠&quot;,&quot;path_word&quot;:&quot;shandianxianew52&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/shandianxianew52/cover/1651085103.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;DC Comics&quot;,&quot;alias&quot;:&quot;DC Comics&quot;,&quot;path_word&quot;:&quot;dccomics&quot;}],&quot;popular&quot;:7386},{&quot;name&quot;:&quot;夜魔俠v4&quot;,&quot;alias&quot;:&quot;夜魔侠ALL-NEW Marvel NOW,夜魔俠v4,夜魔侠v4&quot;,&quot;path_word&quot;:&quot;yemoxiamn&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/yemoxiamn/cover/1650986504.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;Marvel Comics&quot;,&quot;alias&quot;:&quot;Marvel Comics&quot;,&quot;path_word&quot;:&quot;marvel&quot;}],&quot;popular&quot;:4092},{&quot;name&quot;:&quot;世代相承-最佳&quot;,&quot;alias&quot;:&quot;Generations - Wolverine &amp; All-New Wolverine (2017-,世代相承-最佳,世代相承-最佳&quot;,&quot;path_word&quot;:&quot;shidaixiangchengzuijia&quot;,&quot;cover&quot;:&quot;https://hi77-overseas.mangafuna.xyz/shidaixiangchengzuijia/cover/1651041967.jpg.328x422.jpg&quot;,&quot;img_type&quot;:2,&quot;author&quot;:[{&quot;name&quot;:&quot;Marvel Comics&quot;,&quot;alias&quot;:&quot;Marvel Comics&quot;,&quot;path_word&quot;:&quot;marvel&quot;}],&quot;popular&quot;:434}],&quot;total&quot;:65,&quot;limit&quot;:21,&quot;offset&quot;:0}}\" />\n          <option name=\"url\" value=\"https://api.copymanga.net/api/v3/search/comic?format=json&amp;limit=21&amp;offset=0&amp;platform=3&amp;q=new\" />\n        </ResponseHistory>\n      </list>\n    </option>\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=\"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/inspectionProfiles/Project_Default.xml",
    "content": "<component name=\"InspectionProjectProfileManager\">\n  <profile version=\"1.0\">\n    <option name=\"myName\" value=\"Project Default\" />\n    <inspection_tool class=\"AutoCloseableResource\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n      <option name=\"METHOD_MATCHER_CONFIG\" value=\"java.util.Formatter,format,java.io.Writer,append,com.google.common.base.Preconditions,checkNotNull,org.hibernate.Session,close,java.io.PrintWriter,printf,java.io.PrintStream,printf,android.content.Context,obtainStyledAttributes\" />\n    </inspection_tool>\n    <inspection_tool class=\"JavaDoc\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n      <option name=\"TOP_LEVEL_CLASS_OPTIONS\">\n        <value>\n          <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n          <option name=\"REQUIRED_TAGS\" value=\"\" />\n        </value>\n      </option>\n      <option name=\"INNER_CLASS_OPTIONS\">\n        <value>\n          <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n          <option name=\"REQUIRED_TAGS\" value=\"\" />\n        </value>\n      </option>\n      <option name=\"METHOD_OPTIONS\">\n        <value>\n          <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n          <option name=\"REQUIRED_TAGS\" value=\"@return@param@throws or @exception\" />\n        </value>\n      </option>\n      <option name=\"FIELD_OPTIONS\">\n        <value>\n          <option name=\"ACCESS_JAVADOC_REQUIRED_FOR\" value=\"none\" />\n          <option name=\"REQUIRED_TAGS\" value=\"\" />\n        </value>\n      </option>\n      <option name=\"IGNORE_DEPRECATED\" value=\"false\" />\n      <option name=\"IGNORE_JAVADOC_PERIOD\" value=\"true\" />\n      <option name=\"IGNORE_DUPLICATED_THROWS\" value=\"false\" />\n      <option name=\"IGNORE_POINT_TO_ITSELF\" value=\"false\" />\n      <option name=\"myAdditionalJavadocTags\" value=\"array,String,map\" />\n    </inspection_tool>\n    <inspection_tool class=\"JavadocDeclaration\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n      <option name=\"ADDITIONAL_TAGS\" value=\"array,String,map\" />\n    </inspection_tool>\n    <inspection_tool class=\"MissingJavadoc\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n      <option name=\"PACKAGE_SETTINGS\">\n        <Options>\n          <option name=\"ENABLED\" value=\"false\" />\n        </Options>\n      </option>\n      <option name=\"MODULE_SETTINGS\">\n        <Options>\n          <option name=\"ENABLED\" value=\"false\" />\n        </Options>\n      </option>\n      <option name=\"TOP_LEVEL_CLASS_SETTINGS\">\n        <Options>\n          <option name=\"ENABLED\" value=\"false\" />\n        </Options>\n      </option>\n      <option name=\"INNER_CLASS_SETTINGS\">\n        <Options>\n          <option name=\"ENABLED\" value=\"false\" />\n        </Options>\n      </option>\n      <option name=\"METHOD_SETTINGS\">\n        <Options>\n          <option name=\"REQUIRED_TAGS\" value=\"@return@param@throws or @exception\" />\n          <option name=\"ENABLED\" value=\"false\" />\n        </Options>\n      </option>\n      <option name=\"FIELD_SETTINGS\">\n        <Options>\n          <option name=\"ENABLED\" value=\"false\" />\n        </Options>\n      </option>\n    </inspection_tool>\n    <inspection_tool class=\"PreviewAnnotationInFunctionWithParameters\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewApiLevelMustBeValid\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewDimensionRespectsLimit\" enabled=\"true\" level=\"WARNING\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewFontScaleMustBeGreaterThanZero\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewMultipleParameterProviders\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewMustBeTopLevelFunction\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewNeedsComposableAnnotation\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewNotSupportedInUnitTestFiles\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n    <inspection_tool class=\"PreviewPickerAnnotation\" enabled=\"true\" level=\"ERROR\" enabled_by_default=\"true\">\n      <option name=\"composableFile\" value=\"true\" />\n      <option name=\"previewFile\" value=\"true\" />\n    </inspection_tool>\n  </profile>\n</component>"
  },
  {
    "path": ".idea/jsonSchemas.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"JsonSchemaMappingsProjectConfiguration\">\n    <state>\n      <map>\n        <entry key=\"JSON Schema version 4\">\n          <value>\n            <SchemaInfo>\n              <option name=\"name\" value=\"JSON Schema version 4\" />\n              <option name=\"relativePathToSchema\" value=\"http://json-schema.org/draft-04/schema\" />\n              <option name=\"applicationDefined\" value=\"true\" />\n              <option name=\"patterns\">\n                <list>\n                  <Item>\n                    <option name=\"path\" value=\"file://$APPLICATION_CONFIG_DIR$/scratches/scratch_1.json\" />\n                  </Item>\n                  <Item>\n                    <option name=\"path\" value=\"file://$APPLICATION_CONFIG_DIR$/scratches/scratch_4.json\" />\n                  </Item>\n                </list>\n              </option>\n            </SchemaInfo>\n          </value>\n        </entry>\n        <entry key=\"JSON Schema version 7\">\n          <value>\n            <SchemaInfo>\n              <option name=\"name\" value=\"JSON Schema version 7\" />\n              <option name=\"relativePathToSchema\" value=\"http://json-schema.org/draft-07/schema\" />\n              <option name=\"schemaVersion\" value=\"JSON Schema version 7\" />\n              <option name=\"applicationDefined\" value=\"true\" />\n              <option name=\"patterns\">\n                <list>\n                  <Item>\n                    <option name=\"path\" value=\"file://$APPLICATION_CONFIG_DIR$/scratches/scratch_10.json\" />\n                  </Item>\n                </list>\n              </option>\n            </SchemaInfo>\n          </value>\n        </entry>\n      </map>\n    </state>\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.9.22\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_activity_activity_1_8_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.activity:activity:1.8.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/47a9615bbe8011d41921bfc4099a758e/transformed/activity-1.8.2/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/47a9615bbe8011d41921bfc4099a758e/transformed/activity-1.8.2/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/47a9615bbe8011d41921bfc4099a758e/transformed/activity-1.8.2/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.activity/activity/1.8.2/4db2a2efa9046d2bde019dddc6c857c8f67a50cf/activity-1.8.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_activity_activity_compose_1_8_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.activity:activity-compose:1.8.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/5512951b4c8dab523b3f1c67bc8798e1/transformed/activity-compose-1.8.2/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/5512951b4c8dab523b3f1c67bc8798e1/transformed/activity-compose-1.8.2/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/5512951b4c8dab523b3f1c67bc8798e1/transformed/activity-compose-1.8.2/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.activity/activity-compose/1.8.2/6c5ebff07639f79cfcf9f86a3e08a7c9397748f8/activity-compose-1.8.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_activity_activity_ktx_1_8_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.activity:activity-ktx:1.8.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/c5e950b69840c7c0a4e1d5c5185a2f04/transformed/activity-ktx-1.8.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/c5e950b69840c7c0a4e1d5c5185a2f04/transformed/activity-ktx-1.8.2/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/c5e950b69840c7c0a4e1d5c5185a2f04/transformed/activity-ktx-1.8.2/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.activity/activity-ktx/1.8.2/547c83f632a6ffc79c2ed38a2211cea23a8358c1/activity-ktx-1.8.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_4_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.annotation:annotation-experimental:1.4.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/e7e4576f6e600b352238f51b048a38f0/transformed/annotation-experimental-1.4.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/e7e4576f6e600b352238f51b048a38f0/transformed/annotation-experimental-1.4.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/e7e4576f6e600b352238f51b048a38f0/transformed/annotation-experimental-1.4.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.annotation/annotation-experimental/1.4.0/4dc003cb3c5ff16a1c3d09f3d1f7ae7b2d14a9c4/annotation-experimental-1.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_annotation_annotation_jvm_1_7_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.annotation:annotation-jvm:1.7.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.annotation/annotation-jvm/1.7.0/920472d40adcdef5e18708976b3e314f9a636fcd/annotation-jvm-1.7.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.annotation/annotation-jvm/1.7.0/db7fa03a3e5ae4cc48af00b8a990c2fa162f057f/annotation-jvm-1.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_appcompat_appcompat_1_6_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.appcompat:appcompat:1.6.1@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/eb8e80a3b44879c34ca17e0f0d078662/transformed/appcompat-1.6.1/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/eb8e80a3b44879c34ca17e0f0d078662/transformed/appcompat-1.6.1/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/eb8e80a3b44879c34ca17e0f0d078662/transformed/appcompat-1.6.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/eb8e80a3b44879c34ca17e0f0d078662/transformed/appcompat-1.6.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.appcompat/appcompat/1.6.1/ace9a78b961165396147e8691faa18c1b0e48e20/appcompat-1.6.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_6_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.appcompat:appcompat-resources:1.6.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ec9c41bc091da89dafafb3e01524a461/transformed/appcompat-resources-1.6.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ec9c41bc091da89dafafb3e01524a461/transformed/appcompat-resources-1.6.1/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ec9c41bc091da89dafafb3e01524a461/transformed/appcompat-resources-1.6.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.appcompat/appcompat-resources/1.6.1/53fccb3cf4bae3905a487581fb3ff7b9616583a6/appcompat-resources-1.6.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_arch_core_core_common_2_2_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.arch.core:core-common:2.2.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.arch.core/core-common/2.2.0/5e1b8b81dfd5f52c56a8d53b18ca759c19a301f3/core-common-2.2.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.arch.core/core-common/2.2.0/f3ac1460fc6844d5441595a34591af7fc04fd2e5/core-common-2.2.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_arch_core_core_runtime_2_2_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.arch.core:core-runtime:2.2.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/056914b01ec84c9fe5f00772ad275937/transformed/core-runtime-2.2.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/056914b01ec84c9fe5f00772ad275937/transformed/core-runtime-2.2.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/056914b01ec84c9fe5f00772ad275937/transformed/core-runtime-2.2.0/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.arch.core/core-runtime/2.2.0/48630ad88f438e5a603ae74cf4858203d1a595c5/core-runtime-2.2.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_cardview_cardview_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.cardview:cardview:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/6e92d3504dc04cc4aaffc922035b0cc5/transformed/cardview-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6e92d3504dc04cc4aaffc922035b0cc5/transformed/cardview-1.0.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6e92d3504dc04cc4aaffc922035b0cc5/transformed/cardview-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.cardview/cardview/1.0.0/c9f3ce7ca74ad2c978230f4094ba6804c5166f9c/cardview-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_collection_collection_jvm_1_4_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.collection:collection-jvm:1.4.0\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"androidx.collection\" artifactId=\"collection-jvm\" version=\"1.4.0\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.collection/collection-jvm/1.4.0/e209fb7bd1183032f55a0408121c6251a81acb49/collection-jvm-1.4.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.collection/collection-jvm/1.4.0/d85f9e6eecd7ec453dd808c6429dd84650112ac4/collection-jvm-1.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_collection_collection_ktx_1_4_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.collection:collection-ktx:1.4.0\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"androidx.collection\" artifactId=\"collection-ktx\" version=\"1.4.0\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.collection/collection-ktx/1.4.0/2ad14aed781c4a73ed4dbb421966d408a0a06686/collection-ktx-1.4.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.collection/collection-ktx/1.4.0/2ad14aed781c4a73ed4dbb421966d408a0a06686/collection-ktx-1.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_animation_animation_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.animation:animation-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a598a401b0ae2f7f02910516e6124055/transformed/animation-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a598a401b0ae2f7f02910516e6124055/transformed/animation-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a598a401b0ae2f7f02910516e6124055/transformed/animation-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.animation/animation-android/1.6.0/58504392487cb6c8f669e1ac71d949b36ef084d1/animation-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_animation_animation_core_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.animation:animation-core-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/bfe5fbb0e9524484dd2ba843718d498c/transformed/animation-core-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/bfe5fbb0e9524484dd2ba843718d498c/transformed/animation-core-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/bfe5fbb0e9524484dd2ba843718d498c/transformed/animation-core-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.animation/animation-core-android/1.6.0/5f026cb93792662e01612535678aa86a11d74cde/animation-core-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_animation_animation_graphics_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.animation:animation-graphics-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/3059c62b31abe7d394cbc92c02807914/transformed/animation-graphics-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3059c62b31abe7d394cbc92c02807914/transformed/animation-graphics-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3059c62b31abe7d394cbc92c02807914/transformed/animation-graphics-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.animation/animation-graphics-android/1.6.0/713d7d5e60f5fb460c9a23a2a5be354c18acd65a/animation-graphics-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_foundation_foundation_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.foundation:foundation-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/c34140ccc10290af9ca64fb89ccf2ca7/transformed/foundation-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/c34140ccc10290af9ca64fb89ccf2ca7/transformed/foundation-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/c34140ccc10290af9ca64fb89ccf2ca7/transformed/foundation-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.foundation/foundation-android/1.6.0/c8706c9d00a21244d09330c5a71c291bd7decf9/foundation-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_foundation_foundation_layout_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.foundation:foundation-layout-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/6f2933344c1f2ca172d77b3326f4ed05/transformed/foundation-layout-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6f2933344c1f2ca172d77b3326f4ed05/transformed/foundation-layout-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6f2933344c1f2ca172d77b3326f4ed05/transformed/foundation-layout-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.foundation/foundation-layout-android/1.6.0/d7c6460aadb876c0399f1892d695617e731f1e47/foundation-layout-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_material3_material3_android_1_2_0_rc01_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.material3:material3-android:1.2.0-rc01@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/008f6424d43f2e4ae91416bbbc1572b3/transformed/material3-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/008f6424d43f2e4ae91416bbbc1572b3/transformed/material3-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/008f6424d43f2e4ae91416bbbc1572b3/transformed/material3-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.material3/material3-android/1.2.0-rc01/893ce47a6ac320c9d0efa12fce33e12bfb5c1d1/material3-android-1.2.0-rc01-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_material_material_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.material:material-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a060e84f231273f3f2964f3041b2da5a/transformed/material-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a060e84f231273f3f2964f3041b2da5a/transformed/material-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a060e84f231273f3f2964f3041b2da5a/transformed/material-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.material/material-android/1.6.0/caf61e2fb9c853685d9f1fb6c4befe2207c388f0/material-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_material_material_icons_core_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.material:material-icons-core-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/b46545477c4eef09ac562bb6ed0eb79a/transformed/material-icons-core-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b46545477c4eef09ac562bb6ed0eb79a/transformed/material-icons-core-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b46545477c4eef09ac562bb6ed0eb79a/transformed/material-icons-core-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.material/material-icons-core-android/1.6.0/e518df0d8a19c3833f72a24ff667853015e340fd/material-icons-core-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_material_material_ripple_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.material:material-ripple-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/e858243ba10a012f3fd36f06d1b9f7ed/transformed/material-ripple-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/e858243ba10a012f3fd36f06d1b9f7ed/transformed/material-ripple-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/e858243ba10a012f3fd36f06d1b9f7ed/transformed/material-ripple-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.material/material-ripple-android/1.6.0/5658994fca2cfab39445d8960d9609737b5f71be/material-ripple-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_runtime_runtime_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.runtime:runtime-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/78c8f19921f49adc37861e8d4615c384/transformed/runtime-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/78c8f19921f49adc37861e8d4615c384/transformed/runtime-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/78c8f19921f49adc37861e8d4615c384/transformed/runtime-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.runtime/runtime-android/1.6.0/46e1ceaa76a9a58bd5b61cb0ec123b441ec69d75/runtime-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_runtime_runtime_saveable_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.runtime:runtime-saveable-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/276f1365d37a21c12f5cd211b058ecc4/transformed/runtime-saveable-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/276f1365d37a21c12f5cd211b058ecc4/transformed/runtime-saveable-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/276f1365d37a21c12f5cd211b058ecc4/transformed/runtime-saveable-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.runtime/runtime-saveable-android/1.6.0/e36ff9886898fcb4c455c2e9901391f49c6574b5/runtime-saveable-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/48ef0e9b3c2677bfe804f19964a3e562/transformed/ui-release/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/48ef0e9b3c2677bfe804f19964a3e562/transformed/ui-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/48ef0e9b3c2677bfe804f19964a3e562/transformed/ui-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/48ef0e9b3c2677bfe804f19964a3e562/transformed/ui-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-android/1.6.0/a3be40f1e0ca377c9e2082736313f13e57141119/ui-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_geometry_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-geometry-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/22dfc97af5c5032210d366ebc64bc99f/transformed/ui-geometry-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/22dfc97af5c5032210d366ebc64bc99f/transformed/ui-geometry-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/22dfc97af5c5032210d366ebc64bc99f/transformed/ui-geometry-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-geometry-android/1.6.0/2b167ccf642bf99c919cfa98bee1676e8335d1dc/ui-geometry-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_graphics_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-graphics-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/efe179a4df6f69b82ec9f1d718dd8167/transformed/ui-graphics-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/efe179a4df6f69b82ec9f1d718dd8167/transformed/ui-graphics-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/efe179a4df6f69b82ec9f1d718dd8167/transformed/ui-graphics-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-graphics-android/1.6.0/1298b90ac426648ecdcf197c8b1cfe137b7c433f/ui-graphics-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_text_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-text-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/08e371103d5f937c01d7f2c2e6bb65d1/transformed/ui-text-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/08e371103d5f937c01d7f2c2e6bb65d1/transformed/ui-text-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/08e371103d5f937c01d7f2c2e6bb65d1/transformed/ui-text-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-text-android/1.6.0/2a2485216a805d84109cd63cd8d4e2e5a5cadb5e/ui-text-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_tooling_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-tooling-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/e7b2a7fb531285ce40fbc3640ca46398/transformed/ui-tooling-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/e7b2a7fb531285ce40fbc3640ca46398/transformed/ui-tooling-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/e7b2a7fb531285ce40fbc3640ca46398/transformed/ui-tooling-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-tooling-android/1.6.0/c5462dd57a2e392ac2dfcfcc07b694c793c82a73/ui-tooling-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_tooling_data_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-tooling-data-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/1f1c187f596f0cba3d3254b8826b9682/transformed/ui-tooling-data-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/1f1c187f596f0cba3d3254b8826b9682/transformed/ui-tooling-data-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/1f1c187f596f0cba3d3254b8826b9682/transformed/ui-tooling-data-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-tooling-data-android/1.6.0/106401abfb0f95e83de0d129bc8443122809bacd/ui-tooling-data-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_tooling_preview_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-tooling-preview-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/73928ae70ef09814fc74543ceb20fa7f/transformed/ui-tooling-preview-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/73928ae70ef09814fc74543ceb20fa7f/transformed/ui-tooling-preview-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/73928ae70ef09814fc74543ceb20fa7f/transformed/ui-tooling-preview-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-tooling-preview-android/1.6.0/c1cc66505a91b370b6f456d88ab4eba3400300f7/ui-tooling-preview-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_unit_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-unit-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/fc23084f997b44dcdf586a1d4e10b8ca/transformed/ui-unit-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/fc23084f997b44dcdf586a1d4e10b8ca/transformed/ui-unit-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/fc23084f997b44dcdf586a1d4e10b8ca/transformed/ui-unit-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-unit-android/1.6.0/b9b3e53b3ee319c34765d6cf8cebbaed01e25af0/ui-unit-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_compose_ui_ui_util_android_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.compose.ui:ui-util-android:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/0fd4e9f0182e6ee855eee5eb47d53a28/transformed/ui-util-release/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/0fd4e9f0182e6ee855eee5eb47d53a28/transformed/ui-util-release/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/0fd4e9f0182e6ee855eee5eb47d53a28/transformed/ui-util-release/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.ui/ui-util-android/1.6.0/c226e92fd11dfab72261220b7ba604984aa8fbfb/ui-util-android-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_concurrent_concurrent_futures_1_1_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.concurrent:concurrent-futures:1.1.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.concurrent/concurrent-futures/1.1.0/50b7fb98350d5f42a4e49704b03278542293ba48/concurrent-futures-1.1.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.concurrent/concurrent-futures/1.1.0/a27842adf6c42f3d80893bd46e1de4ac024218e7/concurrent-futures-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_constraintlayout_constraintlayout_2_1_4_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.constraintlayout:constraintlayout:2.1.4@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/d3ff9fe3b5e198e632b096ddc1226f31/transformed/constraintlayout-2.1.4/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d3ff9fe3b5e198e632b096ddc1226f31/transformed/constraintlayout-2.1.4/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d3ff9fe3b5e198e632b096ddc1226f31/transformed/constraintlayout-2.1.4/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.constraintlayout/constraintlayout/2.1.4/27e12209e529970f69bc817f349c247ef238fae7/constraintlayout-2.1.4-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.coordinatorlayout:coordinatorlayout:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/709d7acac938c7e6ae2621606ecf12d6/transformed/coordinatorlayout-1.1.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/709d7acac938c7e6ae2621606ecf12d6/transformed/coordinatorlayout-1.1.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/709d7acac938c7e6ae2621606ecf12d6/transformed/coordinatorlayout-1.1.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/709d7acac938c7e6ae2621606ecf12d6/transformed/coordinatorlayout-1.1.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.coordinatorlayout/coordinatorlayout/1.1.0/a15529ac349d76a872ae5ef42b84c320c456cd7f/coordinatorlayout-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_core_core_1_12_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.core:core:1.12.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/814412e5719d0e339a1f18c2dbab2f8b/transformed/core-1.12.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/814412e5719d0e339a1f18c2dbab2f8b/transformed/core-1.12.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/814412e5719d0e339a1f18c2dbab2f8b/transformed/core-1.12.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/814412e5719d0e339a1f18c2dbab2f8b/transformed/core-1.12.0/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.core/core/1.12.0/696658fc9147f9bb2e04c64f77fa0c8a603583d/core-1.12.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_core_core_ktx_1_12_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.core:core-ktx:1.12.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/df29cb887c43f43de5f89550b7152269/transformed/core-ktx-1.12.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/df29cb887c43f43de5f89550b7152269/transformed/core-ktx-1.12.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/df29cb887c43f43de5f89550b7152269/transformed/core-ktx-1.12.0/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.core/core-ktx/1.12.0/e6c10584acda1ffeb12bf3bee451bed5ffbe2705/core-ktx-1.12.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.cursoradapter:cursoradapter:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/f7e10212075239c171d4cb20e65b8165/transformed/cursoradapter-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f7e10212075239c171d4cb20e65b8165/transformed/cursoradapter-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.cursoradapter/cursoradapter/1.0.0/1e323083b41c31fd4d45510dfce50614963c3c6c/cursoradapter-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_customview_customview_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.customview:customview:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/2936a03115bd0c269303399e2c6f10dc/transformed/customview-1.1.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2936a03115bd0c269303399e2c6f10dc/transformed/customview-1.1.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.customview/customview/1.1.0/be631aafb1eb3f64c9cc57083a21a3321cf2e2e1/customview-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_databinding_viewbinding_8_2_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.databinding:viewbinding:8.2.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a631f9a1f0d33af1be0ccddf0397f443/transformed/viewbinding-8.2.2/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a631f9a1f0d33af1be0ccddf0397f443/transformed/viewbinding-8.2.2/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.databinding/viewbinding/8.2.2/a113c3e3e636c709323ea47b3b44e4f0b626f511/viewbinding-8.2.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_documentfile_documentfile_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.documentfile:documentfile:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/d8a8dc203b2da8971c991c9d2e57e01c/transformed/documentfile-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d8a8dc203b2da8971c991c9d2e57e01c/transformed/documentfile-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.documentfile/documentfile/1.0.0/a1bed5cf96db96bd06a2feade98fe55653811dc8/documentfile-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_1_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.drawerlayout:drawerlayout:1.1.1@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/dd90f525a785c6501b40b470be7e9500/transformed/drawerlayout-1.1.1/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/dd90f525a785c6501b40b470be7e9500/transformed/drawerlayout-1.1.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/dd90f525a785c6501b40b470be7e9500/transformed/drawerlayout-1.1.1/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/dd90f525a785c6501b40b470be7e9500/transformed/drawerlayout-1.1.1/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.drawerlayout/drawerlayout/1.1.1/d95f7d9cd7d95cc0c038bbcf9c65f521b56fee55/drawerlayout-1.1.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_dynamicanimation_dynamicanimation_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.dynamicanimation:dynamicanimation:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/766da79e8e85aede3dc952ec708cd527/transformed/dynamicanimation-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/766da79e8e85aede3dc952ec708cd527/transformed/dynamicanimation-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.dynamicanimation/dynamicanimation/1.0.0/5c050e29af5033ff5e2d58ccf657ae92fdfbda4a/dynamicanimation-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_exifinterface_exifinterface_1_3_3_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.exifinterface:exifinterface:1.3.3@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/313cc3a0562985fce4136bd3766d1739/transformed/exifinterface-1.3.3/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/313cc3a0562985fce4136bd3766d1739/transformed/exifinterface-1.3.3/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/313cc3a0562985fce4136bd3766d1739/transformed/exifinterface-1.3.3/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.exifinterface/exifinterface/1.3.3/7019a8493752dd01841de592cccff677e6b8070a/exifinterface-1.3.3-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_exifinterface_exifinterface_1_3_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.exifinterface:exifinterface:1.3.6@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/40c30630f812a70404c3f8749fe623a8/transformed/exifinterface-1.3.6/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/40c30630f812a70404c3f8749fe623a8/transformed/exifinterface-1.3.6/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/40c30630f812a70404c3f8749fe623a8/transformed/exifinterface-1.3.6/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.exifinterface/exifinterface/1.3.6/aeb56286a5af00c1fa61258576e5b8f03a63d05d/exifinterface-1.3.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_fragment_fragment_1_6_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.fragment:fragment:1.6.2@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ec3311c794b9a7d3de16965d04fb10b0/transformed/fragment-1.6.2/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ec3311c794b9a7d3de16965d04fb10b0/transformed/fragment-1.6.2/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ec3311c794b9a7d3de16965d04fb10b0/transformed/fragment-1.6.2/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ec3311c794b9a7d3de16965d04fb10b0/transformed/fragment-1.6.2/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.fragment/fragment/1.6.2/444adb8cd1e1d5d7d5bd92a679bcb91c8e422c55/fragment-1.6.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_fragment_fragment_ktx_1_6_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.fragment:fragment-ktx:1.6.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/226f8b5e7f06d9b58e8f66787650a29b/transformed/fragment-ktx-1.6.2/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/226f8b5e7f06d9b58e8f66787650a29b/transformed/fragment-ktx-1.6.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/226f8b5e7f06d9b58e8f66787650a29b/transformed/fragment-ktx-1.6.2/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.fragment/fragment-ktx/1.6.2/28f33ed9b13c66f57202fc9be92d240337fce030/fragment-ktx-1.6.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_fragment_fragment_testing_1_6_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.fragment:fragment-testing:1.6.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/48e1a281f1caf3df416cfc2d0c24fbb6/transformed/fragment-testing-1.6.2/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/48e1a281f1caf3df416cfc2d0c24fbb6/transformed/fragment-testing-1.6.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/48e1a281f1caf3df416cfc2d0c24fbb6/transformed/fragment-testing-1.6.2/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.fragment/fragment-testing/1.6.2/ac3d30383a35e2c1b00c572f087a045c48a5a3bd/fragment-testing-1.6.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_fragment_fragment_testing_manifest_1_6_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.fragment:fragment-testing-manifest:1.6.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/cadeb72f4706c96e85a723821814f036/transformed/fragment-testing-manifest-1.6.2/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/cadeb72f4706c96e85a723821814f036/transformed/fragment-testing-manifest-1.6.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/cadeb72f4706c96e85a723821814f036/transformed/fragment-testing-manifest-1.6.2/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.fragment/fragment-testing-manifest/1.6.2/9f26b801b4abf49b5cd2fe81cee1ee68591f9f00/fragment-testing-manifest-1.6.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_hilt_hilt_common_1_1_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.hilt:hilt-common:1.1.0\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"androidx.hilt\" artifactId=\"hilt-common\" version=\"1.1.0\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.hilt/hilt-common/1.1.0/9ca9c006cfce81d1435a0735fdab4b9e1166faa1/hilt-common-1.1.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.hilt/hilt-common/1.1.0/856ecdb23b8d76e2e45090a11983c5d487006962/hilt-common-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_hilt_hilt_navigation_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.hilt:hilt-navigation:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/f7e4a69c567fb53846d28f83a71b4b8b/transformed/hilt-navigation-1.1.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f7e4a69c567fb53846d28f83a71b4b8b/transformed/hilt-navigation-1.1.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f7e4a69c567fb53846d28f83a71b4b8b/transformed/hilt-navigation-1.1.0/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.hilt/hilt-navigation/1.1.0/3ac307cbdcb6c029df8c3b775dca05d4f700561e/hilt-navigation-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_hilt_hilt_navigation_compose_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.hilt:hilt-navigation-compose:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ad692cfc384c3809632d74d923dfe81e/transformed/hilt-navigation-compose-1.1.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ad692cfc384c3809632d74d923dfe81e/transformed/hilt-navigation-compose-1.1.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ad692cfc384c3809632d74d923dfe81e/transformed/hilt-navigation-compose-1.1.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.hilt/hilt-navigation-compose/1.1.0/b540805d6c2c35b8d17f903f888a201ec17b507a/hilt-navigation-compose-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_hilt_hilt_work_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.hilt:hilt-work:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/58d913e90f3db44b86e75d9aabc2d5e9/transformed/hilt-work-1.1.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/58d913e90f3db44b86e75d9aabc2d5e9/transformed/hilt-work-1.1.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/58d913e90f3db44b86e75d9aabc2d5e9/transformed/hilt-work-1.1.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.hilt/hilt-work/1.1.0/5b673f915ec6c1698ff8e85850a13189d7eadce7/hilt-work-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.interpolator:interpolator:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/509bf874af2cc46912120e00b46c8ef6/transformed/interpolator-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/509bf874af2cc46912120e00b46c8ef6/transformed/interpolator-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.interpolator/interpolator/1.0.0/fefd5e3cbc479b6b4a9532d05688a1e659e8d3d2/interpolator-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_legacy_legacy_support_core_utils_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.legacy:legacy-support-core-utils:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/4f1a98d68b50683794122c6687e7e0e1/transformed/legacy-support-core-utils-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/4f1a98d68b50683794122c6687e7e0e1/transformed/legacy-support-core-utils-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.legacy/legacy-support-core-utils/1.0.0/46c37f178088153618cfb0afef08ec96c48f93cb/legacy-support-core-utils-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_7_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-common:2.7.0\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"androidx.lifecycle\" artifactId=\"lifecycle-common\" version=\"2.7.0\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common/2.7.0/85334205d65cca70ed0109c3acbd29e22a2d9cb1/lifecycle-common-2.7.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common/2.7.0/de4ccde9dba9e5c3454dd325535aab954ebe94bc/lifecycle-common-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_java8_2_7_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-common-java8:2.7.0\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"androidx.lifecycle\" artifactId=\"lifecycle-common-java8\" version=\"2.7.0\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common-java8/2.7.0/2ad14aed781c4a73ed4dbb421966d408a0a06686/lifecycle-common-java8-2.7.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common-java8/2.7.0/2ad14aed781c4a73ed4dbb421966d408a0a06686/lifecycle-common-java8-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-livedata:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/706a12b8efb495bdc13fda57f48c486e/transformed/lifecycle-livedata-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/706a12b8efb495bdc13fda57f48c486e/transformed/lifecycle-livedata-2.7.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/706a12b8efb495bdc13fda57f48c486e/transformed/lifecycle-livedata-2.7.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-livedata/2.7.0/e1387f4b1f064cea23c46a1326ea46f37b75a851/lifecycle-livedata-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a602bfa640bcfc6a27963a2206def2ce/transformed/lifecycle-livedata-core-2.7.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a602bfa640bcfc6a27963a2206def2ce/transformed/lifecycle-livedata-core-2.7.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a602bfa640bcfc6a27963a2206def2ce/transformed/lifecycle-livedata-core-2.7.0/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-livedata-core/2.7.0/148c40c69e28eb19bdf817bef6e7b0f24bfa51f9/lifecycle-livedata-core-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_ktx_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a13df930316f7a216a685edbfd92aa5e/transformed/lifecycle-livedata-core-ktx-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a13df930316f7a216a685edbfd92aa5e/transformed/lifecycle-livedata-core-ktx-2.7.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a13df930316f7a216a685edbfd92aa5e/transformed/lifecycle-livedata-core-ktx-2.7.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-livedata-core-ktx/2.7.0/679a0782faddfa90863d19babbe2b44ded7d13b/lifecycle-livedata-core-ktx-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_ktx_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-livedata-ktx:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/4c1771ab345a4546a69f8add6d51a550/transformed/lifecycle-livedata-ktx-2.7.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/4c1771ab345a4546a69f8add6d51a550/transformed/lifecycle-livedata-ktx-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/4c1771ab345a4546a69f8add6d51a550/transformed/lifecycle-livedata-ktx-2.7.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-livedata-ktx/2.7.0/2ad14aed781c4a73ed4dbb421966d408a0a06686/lifecycle-livedata-ktx-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_process_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-process:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/63f4eb9519232d3f11426c503e0ae632/transformed/lifecycle-process-2.7.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/63f4eb9519232d3f11426c503e0ae632/transformed/lifecycle-process-2.7.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/63f4eb9519232d3f11426c503e0ae632/transformed/lifecycle-process-2.7.0/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-process/2.7.0/f04655899d8080b83b40bf80dfd149b2723fb945/lifecycle-process-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-runtime:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/1d00ac4453e995766ab6f931037ee40d/transformed/lifecycle-runtime-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/1d00ac4453e995766ab6f931037ee40d/transformed/lifecycle-runtime-2.7.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/1d00ac4453e995766ab6f931037ee40d/transformed/lifecycle-runtime-2.7.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-runtime/2.7.0/3b9fd825868268670401263d41e09e1ec80a3e23/lifecycle-runtime-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_ktx_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-runtime-ktx:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6e6b0052ea7aa7230d7e4b3c0ad8c386/transformed/lifecycle-runtime-ktx-2.7.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6e6b0052ea7aa7230d7e4b3c0ad8c386/transformed/lifecycle-runtime-ktx-2.7.0/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/6e6b0052ea7aa7230d7e4b3c0ad8c386/transformed/lifecycle-runtime-ktx-2.7.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-runtime-ktx/2.7.0/7b0a2de553c0359c8890577f015303a04219b6c5/lifecycle-runtime-ktx-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_service_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-service:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/f7c3039edb1eb173ff1cc04e05beab81/transformed/lifecycle-service-2.7.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f7c3039edb1eb173ff1cc04e05beab81/transformed/lifecycle-service-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f7c3039edb1eb173ff1cc04e05beab81/transformed/lifecycle-service-2.7.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-service/2.7.0/7d104cf042828829f6ecbfc65719326888396721/lifecycle-service-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/33ce502510c1636404393f0e31b78439/transformed/lifecycle-viewmodel-2.7.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/33ce502510c1636404393f0e31b78439/transformed/lifecycle-viewmodel-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/33ce502510c1636404393f0e31b78439/transformed/lifecycle-viewmodel-2.7.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-viewmodel/2.7.0/c4f0ffe7a451136f33c07c6c3cab550688b1e819/lifecycle-viewmodel-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_compose_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2662d536e3dcd2e9dfc3260abc62f1ae/transformed/lifecycle-viewmodel-compose-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2662d536e3dcd2e9dfc3260abc62f1ae/transformed/lifecycle-viewmodel-compose-2.7.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/2662d536e3dcd2e9dfc3260abc62f1ae/transformed/lifecycle-viewmodel-compose-2.7.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-viewmodel-compose/2.7.0/275ed00640ec6cfc4655f5ffe46ac35e0394fd93/lifecycle-viewmodel-compose-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_ktx_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/dd7de4c4906bd403c86a00286045a7f4/transformed/lifecycle-viewmodel-ktx-2.7.0/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/dd7de4c4906bd403c86a00286045a7f4/transformed/lifecycle-viewmodel-ktx-2.7.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/dd7de4c4906bd403c86a00286045a7f4/transformed/lifecycle-viewmodel-ktx-2.7.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-viewmodel-ktx/2.7.0/a96d165dc6197241de8dd3a77779d86e3d44e920/lifecycle-viewmodel-ktx-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_7_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/0488777efb6cde0a840485460746be82/transformed/lifecycle-viewmodel-savedstate-2.7.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/0488777efb6cde0a840485460746be82/transformed/lifecycle-viewmodel-savedstate-2.7.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/0488777efb6cde0a840485460746be82/transformed/lifecycle-viewmodel-savedstate-2.7.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-viewmodel-savedstate/2.7.0/cbf132838873372144077f5c6da9502248505d7c/lifecycle-viewmodel-savedstate-2.7.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.loader:loader:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/890ab1a25c12aec8343c61e8b80902aa/transformed/loader-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/890ab1a25c12aec8343c61e8b80902aa/transformed/loader-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.loader/loader/1.0.0/b9ef587f3e46c7fe5b00264989764e43ff45cada/loader-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_localbroadcastmanager_localbroadcastmanager_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.localbroadcastmanager:localbroadcastmanager:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/2523f25adabee3d14eb97704a30bdc06/transformed/localbroadcastmanager-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2523f25adabee3d14eb97704a30bdc06/transformed/localbroadcastmanager-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.localbroadcastmanager/localbroadcastmanager/1.0.0/3930e99159fd6b7f1d2e7d5fe9af0924ca1faf9/localbroadcastmanager-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_common_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-common:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/12585dd2c9bef7b32bf17022c6024b79/transformed/navigation-common-2.7.6/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/12585dd2c9bef7b32bf17022c6024b79/transformed/navigation-common-2.7.6/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/12585dd2c9bef7b32bf17022c6024b79/transformed/navigation-common-2.7.6/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-common/2.7.6/299363e0aa3fb4826ac8b4b781259bab41595792/navigation-common-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_common_ktx_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-common-ktx:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/7431822a03f3e6245ebc601d75b50883/transformed/navigation-common-ktx-2.7.6/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/7431822a03f3e6245ebc601d75b50883/transformed/navigation-common-ktx-2.7.6/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/7431822a03f3e6245ebc601d75b50883/transformed/navigation-common-ktx-2.7.6/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-common-ktx/2.7.6/2ad14aed781c4a73ed4dbb421966d408a0a06686/navigation-common-ktx-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_compose_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-compose:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/8c085189c354edcba5ed0ba71d8c9a5b/transformed/navigation-compose-2.7.6/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/8c085189c354edcba5ed0ba71d8c9a5b/transformed/navigation-compose-2.7.6/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/8c085189c354edcba5ed0ba71d8c9a5b/transformed/navigation-compose-2.7.6/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-compose/2.7.6/b759250a62331ef854dcbc1aa7783f6aa3f5571/navigation-compose-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_fragment_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-fragment:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2a1f35e07de9bbe1643c950ff5d4c5dd/transformed/navigation-fragment-2.7.6/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/2a1f35e07de9bbe1643c950ff5d4c5dd/transformed/navigation-fragment-2.7.6/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2a1f35e07de9bbe1643c950ff5d4c5dd/transformed/navigation-fragment-2.7.6/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-fragment/2.7.6/125aa820ec810c1d518e40fc607870af788d5cd7/navigation-fragment-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_fragment_ktx_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-fragment-ktx:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/b2a5f135da22ec80b7ab16054455381b/transformed/navigation-fragment-ktx-2.7.6/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b2a5f135da22ec80b7ab16054455381b/transformed/navigation-fragment-ktx-2.7.6/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b2a5f135da22ec80b7ab16054455381b/transformed/navigation-fragment-ktx-2.7.6/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-fragment-ktx/2.7.6/2ad14aed781c4a73ed4dbb421966d408a0a06686/navigation-fragment-ktx-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_runtime_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-runtime:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d6bc851bb0b4583dfe84c1a3dfebcf2d/transformed/navigation-runtime-2.7.6/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d6bc851bb0b4583dfe84c1a3dfebcf2d/transformed/navigation-runtime-2.7.6/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/d6bc851bb0b4583dfe84c1a3dfebcf2d/transformed/navigation-runtime-2.7.6/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-runtime/2.7.6/136cdad1fe68a293a074fbdfd06242a939269ef9/navigation-runtime-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_runtime_ktx_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-runtime-ktx:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a614755fb3b6ce3507ced13488dbd029/transformed/navigation-runtime-ktx-2.7.6/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a614755fb3b6ce3507ced13488dbd029/transformed/navigation-runtime-ktx-2.7.6/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a614755fb3b6ce3507ced13488dbd029/transformed/navigation-runtime-ktx-2.7.6/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-runtime-ktx/2.7.6/2ad14aed781c4a73ed4dbb421966d408a0a06686/navigation-runtime-ktx-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_ui_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-ui:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/bf228cec4de0e3b9c9971de667703803/transformed/navigation-ui-2.7.6/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/bf228cec4de0e3b9c9971de667703803/transformed/navigation-ui-2.7.6/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/bf228cec4de0e3b9c9971de667703803/transformed/navigation-ui-2.7.6/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-ui/2.7.6/23473de85ea8510077e13d7f33fd0b107331afed/navigation-ui-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_navigation_navigation_ui_ktx_2_7_6_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.navigation:navigation-ui-ktx:2.7.6@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/8e6530087ee48da3438a549416bb50cd/transformed/navigation-ui-ktx-2.7.6/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/8e6530087ee48da3438a549416bb50cd/transformed/navigation-ui-ktx-2.7.6/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/8e6530087ee48da3438a549416bb50cd/transformed/navigation-ui-ktx-2.7.6/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.navigation/navigation-ui-ktx/2.7.6/2ad14aed781c4a73ed4dbb421966d408a0a06686/navigation-ui-ktx-2.7.6-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_paging_paging_common_3_2_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.paging:paging-common:3.2.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.paging/paging-common/3.2.1/48d6af8b2cfb4da25557588b471557fa0751efbb/paging-common-3.2.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.paging/paging-common/3.2.1/7129db9ec65cf48bdce86252d303779ab88fcff6/paging-common-3.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_paging_paging_common_ktx_3_2_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.paging:paging-common-ktx:3.2.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.paging/paging-common-ktx/3.2.1/2ad14aed781c4a73ed4dbb421966d408a0a06686/paging-common-ktx-3.2.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.paging/paging-common-ktx/3.2.1/2ad14aed781c4a73ed4dbb421966d408a0a06686/paging-common-ktx-3.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_paging_paging_compose_3_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.paging:paging-compose:3.2.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/5042683fb2ef3e9f7816f737c7f19b9c/transformed/paging-compose-3.2.1/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/5042683fb2ef3e9f7816f737c7f19b9c/transformed/paging-compose-3.2.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/5042683fb2ef3e9f7816f737c7f19b9c/transformed/paging-compose-3.2.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.paging/paging-compose/3.2.1/ed29f6599dfe2c7e09dfa45d0b02e11c49356020/paging-compose-3.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_paging_paging_runtime_3_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.paging:paging-runtime:3.2.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/dd0381036a0adc8d88c9a42be0c59ddb/transformed/paging-runtime-3.2.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/dd0381036a0adc8d88c9a42be0c59ddb/transformed/paging-runtime-3.2.1/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/dd0381036a0adc8d88c9a42be0c59ddb/transformed/paging-runtime-3.2.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.paging/paging-runtime/3.2.1/fda78b88dadde7baf3922cf0c72fdc4aad009a63/paging-runtime-3.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_paging_paging_runtime_ktx_3_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.paging:paging-runtime-ktx:3.2.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/2adc6b64a46242a77bb29f52e63955af/transformed/paging-runtime-ktx-3.2.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2adc6b64a46242a77bb29f52e63955af/transformed/paging-runtime-ktx-3.2.1/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2adc6b64a46242a77bb29f52e63955af/transformed/paging-runtime-ktx-3.2.1/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.paging/paging-runtime-ktx/3.2.1/2ad14aed781c4a73ed4dbb421966d408a0a06686/paging-runtime-ktx-3.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_palette_palette_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.palette:palette:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/de1499579aff8f42f4bbc5ec3e415e67/transformed/palette-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/de1499579aff8f42f4bbc5ec3e415e67/transformed/palette-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.palette/palette/1.0.0/ac50de11029495e4bc50d2594d4b37e260607782/palette-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_palette_palette_ktx_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.palette:palette-ktx:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/95a2440129bf0717d24d38f8b05f296b/transformed/palette-ktx-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/95a2440129bf0717d24d38f8b05f296b/transformed/palette-ktx-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.palette/palette-ktx/1.0.0/c8341515e46c3ded4b875ce1eaf42350239de824/palette-ktx-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_preference_preference_1_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.preference:preference:1.2.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/58678a8ac3f4da435de13e3c6bffe913/transformed/preference-1.2.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/58678a8ac3f4da435de13e3c6bffe913/transformed/preference-1.2.1/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/58678a8ac3f4da435de13e3c6bffe913/transformed/preference-1.2.1/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.preference/preference/1.2.1/ab5e929e8738e3251b1740fea406ef36e91382a6/preference-1.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_preference_preference_ktx_1_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.preference:preference-ktx:1.2.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b78de6494f8ad55034eb95f55544a08d/transformed/preference-ktx-1.2.1/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b78de6494f8ad55034eb95f55544a08d/transformed/preference-ktx-1.2.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/b78de6494f8ad55034eb95f55544a08d/transformed/preference-ktx-1.2.1/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.preference/preference-ktx/1.2.1/c8df4bdd1cf69b87cbab7120ee314c2c2f6c1bd3/preference-ktx-1.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_print_print_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.print:print:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a9c4d82fde4d528acd36c3f228224a24/transformed/print-1.0.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/a9c4d82fde4d528acd36c3f228224a24/transformed/print-1.0.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/a9c4d82fde4d528acd36c3f228224a24/transformed/print-1.0.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.print/print/1.0.0/71fc2d9acf7cce6b96230c5af263268b1664914a/print-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_recyclerview_recyclerview_1_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.recyclerview:recyclerview:1.2.1@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/cca35b520e956ca4a4f6655c94b60045/transformed/recyclerview-1.2.1/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/cca35b520e956ca4a4f6655c94b60045/transformed/recyclerview-1.2.1/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/cca35b520e956ca4a4f6655c94b60045/transformed/recyclerview-1.2.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/cca35b520e956ca4a4f6655c94b60045/transformed/recyclerview-1.2.1/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.recyclerview/recyclerview/1.2.1/f0f93e67af3f7417bdd560d5142f6dec4fe629c3/recyclerview-1.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_resourceinspection_resourceinspection_annotation_1_0_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.resourceinspection:resourceinspection-annotation:1.0.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.resourceinspection/resourceinspection-annotation/1.0.1/8c21f8ff5d96d5d52c948707f7e4d6ca6773feef/resourceinspection-annotation-1.0.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.resourceinspection/resourceinspection-annotation/1.0.1/a1c91a3cf63fd51a8e755747186d97585f955ae3/resourceinspection-annotation-1.0.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_room_room_common_2_6_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.room:room-common:2.6.1\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"androidx.room\" artifactId=\"room-common\" version=\"2.6.1\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.room/room-common/2.6.1/ff1b9580850a9b7eef56554e356628d225785265/room-common-2.6.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.room/room-common/2.6.1/c04c7202f74aed470c956e50f032ab6d84bff312/room-common-2.6.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_room_room_ktx_2_6_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.room:room-ktx:2.6.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d181d9140a8a86aa0f634c51ed92a013/transformed/room-ktx-2.6.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/d181d9140a8a86aa0f634c51ed92a013/transformed/room-ktx-2.6.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d181d9140a8a86aa0f634c51ed92a013/transformed/room-ktx-2.6.1/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.room/room-ktx/2.6.1/dde5739324784ec695041f2c447905111a8adbe6/room-ktx-2.6.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_room_room_migration_2_6_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.room:room-migration:2.6.1\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"androidx.room\" artifactId=\"room-migration\" version=\"2.6.1\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.room/room-migration/2.6.1/8d8218e4ccfe9b34485619a8ca68f8760840301d/room-migration-2.6.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.room/room-migration/2.6.1/af5f6b81b738cb220c1bc5aff4d439b83aa8760f/room-migration-2.6.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_room_room_runtime_2_6_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.room:room-runtime:2.6.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/68d443a55d0308beb775f014aceb7396/transformed/room-runtime-2.6.1/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/68d443a55d0308beb775f014aceb7396/transformed/room-runtime-2.6.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/68d443a55d0308beb775f014aceb7396/transformed/room-runtime-2.6.1/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.room/room-runtime/2.6.1/32d0372c48888813c86c9fde561182c68745154d/room-runtime-2.6.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_room_room_testing_2_6_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.room:room-testing:2.6.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b3403668d12c7fc3120612877286bf3c/transformed/room-testing-2.6.1/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b3403668d12c7fc3120612877286bf3c/transformed/room-testing-2.6.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/b3403668d12c7fc3120612877286bf3c/transformed/room-testing-2.6.1/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.room/room-testing/2.6.1/a1ac7145802058a30cd86461af2ec1b5af11f2da/room-testing-2.6.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_savedstate_savedstate_1_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.savedstate:savedstate:1.2.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/3c03813491c1677a0e2963b5dad874ef/transformed/savedstate-1.2.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3c03813491c1677a0e2963b5dad874ef/transformed/savedstate-1.2.1/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3c03813491c1677a0e2963b5dad874ef/transformed/savedstate-1.2.1/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.savedstate/savedstate/1.2.1/58d4c9fd35e826d3bce813974006451ee9ba4344/savedstate-1.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_savedstate_savedstate_ktx_1_2_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.savedstate:savedstate-ktx:1.2.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/3e477ee31df4e45b766785f59db850bb/transformed/savedstate-ktx-1.2.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3e477ee31df4e45b766785f59db850bb/transformed/savedstate-ktx-1.2.1/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3e477ee31df4e45b766785f59db850bb/transformed/savedstate-ktx-1.2.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.savedstate/savedstate-ktx/1.2.1/396eb83ce13cac3986e1e8a8b60f60ac0447ffbf/savedstate-ktx-1.2.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_slidingpanelayout_slidingpanelayout_1_2_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.slidingpanelayout:slidingpanelayout:1.2.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/23cc1b8ec9f96428238b32100ec89f29/transformed/slidingpanelayout-1.2.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/23cc1b8ec9f96428238b32100ec89f29/transformed/slidingpanelayout-1.2.0/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/23cc1b8ec9f96428238b32100ec89f29/transformed/slidingpanelayout-1.2.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/23cc1b8ec9f96428238b32100ec89f29/transformed/slidingpanelayout-1.2.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.slidingpanelayout/slidingpanelayout/1.2.0/6cdf3fd538b995c58d602da7114a92fdeeff92ac/slidingpanelayout-1.2.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_sqlite_sqlite_2_4_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.sqlite:sqlite:2.4.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/612a7a1215a16a12b70142dca22227ac/transformed/sqlite-2.4.0/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/612a7a1215a16a12b70142dca22227ac/transformed/sqlite-2.4.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/612a7a1215a16a12b70142dca22227ac/transformed/sqlite-2.4.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.sqlite/sqlite/2.4.0/64eec23481a9132037f83e036924d7d584a17c3d/sqlite-2.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_sqlite_sqlite_framework_2_4_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.sqlite:sqlite-framework:2.4.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6ca0a9760e54d3a2d29a00a3af092844/transformed/sqlite-framework-2.4.0/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/6ca0a9760e54d3a2d29a00a3af092844/transformed/sqlite-framework-2.4.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/6ca0a9760e54d3a2d29a00a3af092844/transformed/sqlite-framework-2.4.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.sqlite/sqlite-framework/2.4.0/edd5d14792596229407204bf8e4a68e6f9b6cddc/sqlite-framework-2.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_startup_startup_runtime_1_1_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.startup:startup-runtime:1.1.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b20d7f3060ba3226d9cb4ac1530867a3/transformed/startup-runtime-1.1.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/b20d7f3060ba3226d9cb4ac1530867a3/transformed/startup-runtime-1.1.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/b20d7f3060ba3226d9cb4ac1530867a3/transformed/startup-runtime-1.1.1/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.startup/startup-runtime/1.1.1/714974d4ab4858eab9395d3b048002108b62cf0a/startup-runtime-1.1.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_annotation_1_0_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test:annotation:1.0.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ed587ab5d1e0ce8092977d564e11a4e6/transformed/annotation-1.0.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ed587ab5d1e0ce8092977d564e11a4e6/transformed/annotation-1.0.1/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test/annotation/1.0.1/d922fcf4c7ae6c3b54012d21e594409c6c6ac156/annotation-1.0.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_core_1_5_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test:core:1.5.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/7786c57adea0dd30d715b18a5e8af80c/transformed/core-1.5.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/7786c57adea0dd30d715b18a5e8af80c/transformed/core-1.5.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/7786c57adea0dd30d715b18a5e8af80c/transformed/core-1.5.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test/core/1.5.0/50a7c88bc23efab4bed11093b47197d11ab3d5a0/core-1.5.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test/core/1.5.0/d4ea5ffd68fc05c1e952467fb884f0d82b44ec3b/core-1.5.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_5_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test.espresso:espresso-core:3.5.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2af681ca80c4de880445742fc6e288e6/transformed/espresso-core-3.5.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/2af681ca80c4de880445742fc6e288e6/transformed/espresso-core-3.5.1/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.espresso/espresso-core/3.5.1/5aa814b4dae9b17188d620668107d85e687388de/espresso-core-3.5.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.espresso/espresso-core/3.5.1/50bb4dd95e68eb3fdc986995afab6730be477cdb/espresso-core-3.5.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_5_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test.espresso:espresso-idling-resource:3.5.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ee16007fd3b1d148fc10d88c3a0c34f3/transformed/espresso-idling-resource-3.5.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ee16007fd3b1d148fc10d88c3a0c34f3/transformed/espresso-idling-resource-3.5.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.espresso/espresso-idling-resource/3.5.1/331f1323e408dc60d9a8bea1eb40a2aa569f8091/espresso-idling-resource-3.5.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.espresso/espresso-idling-resource/3.5.1/7dd3d807f81bd316fe725ad5ab60f7afdad14607/espresso-idling-resource-3.5.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_ext_junit_1_1_5_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test.ext:junit:1.1.5@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/50c47f78b643103c28d2f8328907457d/transformed/junit-1.1.5/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/50c47f78b643103c28d2f8328907457d/transformed/junit-1.1.5/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.ext/junit/1.1.5/ee5294c4eb3c3b3ba1d1b0a347ee5d902b1748ee/junit-1.1.5-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.ext/junit/1.1.5/e59336d689cf66c42c13a8505fbd83826163431f/junit-1.1.5-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_monitor_1_6_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test:monitor:1.6.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/676fc15c1cdc7865254f7ae8ba2632e2/transformed/monitor-1.6.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/676fc15c1cdc7865254f7ae8ba2632e2/transformed/monitor-1.6.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test/monitor/1.6.0/8fca905beed7a63d62777fc7cbb94bea33c1261/monitor-1.6.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test/monitor/1.6.0/52740979540a082b8b05e1a050ad88b89655d964/monitor-1.6.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_runner_1_5_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test:runner:1.5.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/3c43ed2d27364e23fd63ab18eae19776/transformed/runner-1.5.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3c43ed2d27364e23fd63ab18eae19776/transformed/runner-1.5.2/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test/runner/1.5.2/6f61644c4619fe5390973846edfd7704d0db55fd/runner-1.5.2-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test/runner/1.5.2/afd05fc4f8a8375097741bd497654ccbefd63b89/runner-1.5.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_test_services_storage_1_4_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.test.services:storage:1.4.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/2ebf05ae32a953a8b795e75f5c4cac4d/transformed/storage-1.4.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/2ebf05ae32a953a8b795e75f5c4cac4d/transformed/storage-1.4.2/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.services/storage/1.4.2/edb6438b0e7e21c66b22184eebdb13cd5167161a/storage-1.4.2-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.test.services/storage/1.4.2/7653e58ad020a74392900229f15971ffb69d57ea/storage-1.4.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_tracing_tracing_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.tracing:tracing:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/52fdda515e057ae267d8cdb23a6e0fc9/transformed/tracing-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/52fdda515e057ae267d8cdb23a6e0fc9/transformed/tracing-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.tracing/tracing/1.0.0/aa6dafdce323d80a993c5427cf81d5072f023c8c/tracing-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_transition_transition_1_2_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.transition:transition:1.2.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/f3bc122eedb22e4dbbb16e4eb48ef909/transformed/transition-1.2.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f3bc122eedb22e4dbbb16e4eb48ef909/transformed/transition-1.2.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f3bc122eedb22e4dbbb16e4eb48ef909/transformed/transition-1.2.0/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/f3bc122eedb22e4dbbb16e4eb48ef909/transformed/transition-1.2.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.transition/transition/1.2.0/65d2a5dab39f120d3f584fdead252ce81ec7dbee/transition-1.2.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_transition_transition_1_4_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.transition:transition:1.4.1@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ebce7786eaecf07d6745a773daba9c88/transformed/transition-1.4.1/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ebce7786eaecf07d6745a773daba9c88/transformed/transition-1.4.1/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ebce7786eaecf07d6745a773daba9c88/transformed/transition-1.4.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ebce7786eaecf07d6745a773daba9c88/transformed/transition-1.4.1/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.transition/transition/1.4.1/975f706c6c0892d0dfaa416cf04f469cfb0a4343/transition-1.4.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.vectordrawable:vectordrawable:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/919ccb48ccdfff80f1a3736243a35aba/transformed/vectordrawable-1.1.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/919ccb48ccdfff80f1a3736243a35aba/transformed/vectordrawable-1.1.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.vectordrawable/vectordrawable/1.1.0/1e0694477eed874c50c54b547cc3e5a62a57a62b/vectordrawable-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.vectordrawable:vectordrawable-animated:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/7a1f4f4e4ce114a27ac9a6a0e0e175db/transformed/vectordrawable-animated-1.1.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/7a1f4f4e4ce114a27ac9a6a0e0e175db/transformed/vectordrawable-animated-1.1.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.vectordrawable/vectordrawable-animated/1.1.0/871a7705cd03bc246947638c712cdd11378233ff/vectordrawable-animated-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.versionedparcelable:versionedparcelable:1.1.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ed2ba78ae5d267cc70a256a75c79164b/transformed/versionedparcelable-1.1.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ed2ba78ae5d267cc70a256a75c79164b/transformed/versionedparcelable-1.1.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.versionedparcelable/versionedparcelable/1.1.1/d9085927216387af679d18b6f472bc0fc5c7cc81/versionedparcelable-1.1.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_viewpager2_viewpager2_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.viewpager2:viewpager2:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/285a24db186bd1b6732baf2fd1390443/transformed/viewpager2-1.0.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/285a24db186bd1b6732baf2fd1390443/transformed/viewpager2-1.0.0/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/285a24db186bd1b6732baf2fd1390443/transformed/viewpager2-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/285a24db186bd1b6732baf2fd1390443/transformed/viewpager2-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.viewpager2/viewpager2/1.0.0/3c3569044e6969f1ee5c3aa03b08e6717a2d782f/viewpager2-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.viewpager:viewpager:1.0.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/d218fdcfdc6eba8e3842535109aaa074/transformed/viewpager-1.0.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/d218fdcfdc6eba8e3842535109aaa074/transformed/viewpager-1.0.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.viewpager/viewpager/1.0.0/db045f92188b9d247d5f556866f8861ab68528f0/viewpager-1.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_work_work_runtime_2_9_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.work:work-runtime:2.9.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/777778058a9f79d1a33e949e5f8530e5/transformed/work-runtime-2.9.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/777778058a9f79d1a33e949e5f8530e5/transformed/work-runtime-2.9.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/777778058a9f79d1a33e949e5f8530e5/transformed/work-runtime-2.9.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.work/work-runtime/2.9.0/469f3a707823cb36415ab2cfcd0b0c7663734200/work-runtime-2.9.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__androidx_work_work_runtime_ktx_2_9_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: androidx.work:work-runtime-ktx:2.9.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/214bb681f4d3ad6d4eedefc0a68cdc3e/transformed/work-runtime-ktx-2.9.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/214bb681f4d3ad6d4eedefc0a68cdc3e/transformed/work-runtime-ktx-2.9.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/214bb681f4d3ad6d4eedefc0a68cdc3e/transformed/work-runtime-ktx-2.9.0/res\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.work/work-runtime-ktx/2.9.0/2ad14aed781c4a73ed4dbb421966d408a0a06686/work-runtime-ktx-2.9.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_github_KotatsuApp_subsampling_scale_image_view_1b19231b2f_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.github.KotatsuApp:subsampling-scale-image-view:1b19231b2f@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/c5f817211fc42a77f9493b5b15c3f031/transformed/subsampling-scale-image-view-1b19231b2f/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/c5f817211fc42a77f9493b5b15c3f031/transformed/subsampling-scale-image-view-1b19231b2f/res\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/c5f817211fc42a77f9493b5b15c3f031/transformed/subsampling-scale-image-view-1b19231b2f/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.KotatsuApp/subsampling-scale-image-view/1b19231b2f/1bbe8af8663ee63ab7daca88924b4d6340e2bc94/subsampling-scale-image-view-1b19231b2f-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_github_bumptech_glide_annotations_4_15_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.github.bumptech.glide:annotations:4.15.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/annotations/4.15.0/e8bf9138f3938fa76748bd1684d20df414321432/annotations-4.15.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/annotations/4.15.0/6459b16bd728a69dbda7d50a91fea2d460ff2b05/annotations-4.15.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/annotations/4.15.0/11688c5741685784b8e9abbef2089ae8fe6a5bd9/annotations-4.15.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_github_bumptech_glide_disklrucache_4_15_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.github.bumptech.glide:disklrucache:4.15.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/disklrucache/4.15.0/dc9dde980bc49b0fb0ed02d67b4f321b7ae04422/disklrucache-4.15.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/disklrucache/4.15.0/8b10d6eeabac2ed327826c71d4600f6da1a313e6/disklrucache-4.15.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/disklrucache/4.15.0/1df4fc09c319100d2d61c90d661f6ebd66a4a931/disklrucache-4.15.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_github_bumptech_glide_gifdecoder_4_15_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.github.bumptech.glide:gifdecoder:4.15.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/16a184a077d501060a20f0c517048626/transformed/gifdecoder-4.15.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/16a184a077d501060a20f0c517048626/transformed/gifdecoder-4.15.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/16a184a077d501060a20f0c517048626/transformed/gifdecoder-4.15.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/gifdecoder/4.15.0/86e66234db864235d5181a4c4f0c36973f8c83b1/gifdecoder-4.15.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/gifdecoder/4.15.0/c0ba7560f5adf944428742ece8262a8aa78e35f5/gifdecoder-4.15.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_github_bumptech_glide_glide_4_15_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.github.bumptech.glide:glide:4.15.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/59d34931c7bc8ef2e690f361ed0114c2/transformed/glide-4.15.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/59d34931c7bc8ef2e690f361ed0114c2/transformed/glide-4.15.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/59d34931c7bc8ef2e690f361ed0114c2/transformed/glide-4.15.0/res\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/glide/4.15.0/298a72bfdddfa938d35bcbbb61d426952f8f8ffc/glide-4.15.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/glide/4.15.0/13b70a804589f032ab619da58236f3a955fcc97d/glide-4.15.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_github_solkin_disk_lru_cache_1_4_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.github.solkin:disk-lru-cache:1.4@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/bd3bffcd6ef44a8a873636b92f601fc3/transformed/disk-lru-cache-1.4/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/bd3bffcd6ef44a8a873636b92f601fc3/transformed/disk-lru-cache-1.4/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.solkin/disk-lru-cache/1.4/b9088d64cc20b367947c1dd7d05d956f5360cbba/disk-lru-cache-1.4-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_accompanist_accompanist_pager_0_31_3_beta_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.accompanist:accompanist-pager:0.31.3-beta@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/7bcfe4dee57eaef956400b7a87acd93b/transformed/accompanist-pager-0.31.3-beta/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/7bcfe4dee57eaef956400b7a87acd93b/transformed/accompanist-pager-0.31.3-beta/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.accompanist/accompanist-pager/0.31.3-beta/2af195706522d6b289cd959d95a2f8db88710f50/accompanist-pager-0.31.3-beta-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.accompanist/accompanist-pager/0.31.3-beta/788a94b8f3a309737ff715ddf039b73c9f4abcf0/accompanist-pager-0.31.3-beta-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_accompanist_accompanist_pager_indicators_0_31_3_beta_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.accompanist:accompanist-pager-indicators:0.31.3-beta@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/f0df1968495bd31c0f72aadf131989dc/transformed/accompanist-pager-indicators-0.31.3-beta/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/f0df1968495bd31c0f72aadf131989dc/transformed/accompanist-pager-indicators-0.31.3-beta/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.accompanist/accompanist-pager-indicators/0.31.3-beta/8325e64a13482d1894ca2e37799a4cdde126951a/accompanist-pager-indicators-0.31.3-beta-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.accompanist/accompanist-pager-indicators/0.31.3-beta/473178bb6e8c6ebdb08534f14f328e7201587696/accompanist-pager-indicators-0.31.3-beta-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_accompanist_accompanist_themeadapter_material3_0_33_1_alpha_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.accompanist:accompanist-themeadapter-material3:0.33.1-alpha@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/358512e37390ab2a4e76c03f2378b903/transformed/accompanist-themeadapter-material3-0.33.1-alpha/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/358512e37390ab2a4e76c03f2378b903/transformed/accompanist-themeadapter-material3-0.33.1-alpha/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/358512e37390ab2a4e76c03f2378b903/transformed/accompanist-themeadapter-material3-0.33.1-alpha/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.accompanist/accompanist-themeadapter-material3/0.33.1-alpha/19f2861d2d1953e25e98eef82edc918c82965b4e/accompanist-themeadapter-material3-0.33.1-alpha-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.accompanist/accompanist-themeadapter-material3/0.33.1-alpha/4bc18576d15c9269a4d280c2a528ebf4d462b6f5/accompanist-themeadapter-material3-0.33.1-alpha-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_android_material_material_1_11_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.android.material:material:1.11.0@aar\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/1fea1f91d0869ad399b49cede6dc5f43/transformed/material-1.11.0/annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/1fea1f91d0869ad399b49cede6dc5f43/transformed/material-1.11.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/1fea1f91d0869ad399b49cede6dc5f43/transformed/material-1.11.0/res\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/1fea1f91d0869ad399b49cede6dc5f43/transformed/material-1.11.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.android.material/material/1.11.0/47456a5ab79e72baca757532823ea1fa08e001d3/material-1.11.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_code_findbugs_jsr305_3_0_2.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.code.findbugs:jsr305:3.0.2\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/3.0.2/25ea2e8b0c338a877313bd4672d3fe056ea78f0d/jsr305-3.0.2.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/3.0.2/7cb5b4e91eb0741882c8fefb2fd0338eff9857c/jsr305-3.0.2-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/3.0.2/b19b5927c2c25b6c70f093767041e641ae0b1b35/jsr305-3.0.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_code_gson_gson_2_10_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.code.gson:gson:2.10.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.10.1/b3add478d4382b78ea20b1671390a858002feb6c/gson-2.10.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.10.1/9cca04b7347a417baf90858f7cc59d82b44fdd11/gson-2.10.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.10.1/982a90132e942f302e6fe79d6e78c4bc2e998569/gson-2.10.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_dagger_dagger_2_48_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.dagger:dagger:2.48.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger/2.48.1/f3e10ae777850a8110b7ec583df150065ff9bc2b/dagger-2.48.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger/2.48.1/f7358447a4c4b86f26896efcf0c9538c238daffc/dagger-2.48.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/dagger/2.48.1/802fa05c7caba674d447a2f02257f38f2e7f9b96/dagger-2.48.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_dagger_dagger_lint_aar_2_48_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.dagger:dagger-lint-aar:2.48.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/5b8a120b69378c5c9718e2868bbd1c24/transformed/dagger-lint-aar-2.48.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/5b8a120b69378c5c9718e2868bbd1c24/transformed/dagger-lint-aar-2.48.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC />\n    <SOURCES />\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_dagger_hilt_android_2_48_1_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.dagger:hilt-android:2.48.1@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/46084795583bf1b2fcd724f4e0348968/transformed/hilt-android-2.48.1/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/46084795583bf1b2fcd724f4e0348968/transformed/hilt-android-2.48.1/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/hilt-android/2.48.1/564a87459b16f62fa946d7da84a4762c0ad5c981/hilt-android-2.48.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/hilt-android/2.48.1/284d4a1ecf21d1c0470408e70f7e805c207135c2/hilt-android-2.48.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_dagger_hilt_core_2_48_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.dagger:hilt-core:2.48.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/hilt-core/2.48.1/f28429fcfabf0719b76c50709bcfd64106e7c9bf/hilt-core-2.48.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/hilt-core/2.48.1/356f2cb03be5ac0a724914a5170d3a07bd4380fe/hilt-core-2.48.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.dagger/hilt-core/2.48.1/1a781982d1492581f28b66994e7bc9562f0cbf25/hilt-core-2.48.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_google_guava_listenablefuture_1_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.google.guava:listenablefuture:1.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.guava/listenablefuture/1.0/c949a840a6acbc5268d088e47b04177bf90b3cad/listenablefuture-1.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.guava/listenablefuture/1.0/c6fc3e29c8cc24b39c2cd8f66b41bf40e342901c/listenablefuture-1.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.guava/listenablefuture/1.0/be1234988ac73d61e52e35a912169b06020caa7/listenablefuture-1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_mikepenz_aboutlibraries_10_5_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.mikepenz:aboutlibraries:10.5.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/3d60942b22f25b22e719b9d911d7e183/transformed/aboutlibraries-10.5.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3d60942b22f25b22e719b9d911d7e183/transformed/aboutlibraries-10.5.2/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/3d60942b22f25b22e719b9d911d7e183/transformed/aboutlibraries-10.5.2/res\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mikepenz/aboutlibraries/10.5.2/9ec195474faaedc91dfe3b1f9a64f511677fb18a/aboutlibraries-10.5.2-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mikepenz/aboutlibraries/10.5.2/60ec37e8405777d436bc04ce0942356638327abe/aboutlibraries-10.5.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_mikepenz_aboutlibraries_core_android_debug_10_5_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.mikepenz:aboutlibraries-core-android-debug:10.5.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/fa71d2a43325d95c6918ef49d45f000f/transformed/aboutlibraries-core-debug/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/fa71d2a43325d95c6918ef49d45f000f/transformed/aboutlibraries-core-debug/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mikepenz/aboutlibraries-core-android-debug/10.5.2/66841d233bf4a7d4291b4d602fc8c1e007b67c1f/aboutlibraries-core-android-debug-10.5.2-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.mikepenz/aboutlibraries-core-android-debug/10.5.2/536a8554a433a6bdcca6b1e8a2ed887c82a7e407/aboutlibraries-core-android-debug-10.5.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_javawriter_2_1_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup:javawriter:2.1.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup/javawriter/2.1.1/67ff45d9ae02e583d0f9b3432a5ebbe05c30c966/javawriter-2.1.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup/javawriter/2.1.1/f591a105db78771d0a1e7a277b3747556c528c22/javawriter-2.1.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup/javawriter/2.1.1/5b31387d839a5cdaf5b6de3990da01f7f2b963c5/javawriter-2.1.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_moshi_moshi_1_15_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup.moshi:moshi:1.15.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.moshi/moshi/1.15.0/bfefc77019c04fb3e1ad94abb0a2c141a78bbbd8/moshi-1.15.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.moshi/moshi/1.15.0/3781df01d04c158f5a9589ab662c234ee2617751/moshi-1.15.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.moshi/moshi/1.15.0/a21adfe8e16fa82e4f6dbb313536a915ff6e06f7/moshi-1.15.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_moshi_moshi_kotlin_1_15_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup.moshi:moshi-kotlin:1.15.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.moshi/moshi-kotlin/1.15.0/b923ca20f795285c15fa469856894d8619862d77/moshi-kotlin-1.15.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.moshi/moshi-kotlin/1.15.0/956ae2f2e4f0a77bc0b055a59aa47dba3a365e1d/moshi-kotlin-1.15.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.moshi/moshi-kotlin/1.15.0/4f6cdecf06941b7953af4d4ded4e74c0ed449a4d/moshi-kotlin-1.15.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_okhttp3_logging_interceptor_4_9_3.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup.okhttp3:logging-interceptor:4.9.3\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/logging-interceptor/4.9.3/d7786efea637a62603352985d9a229c206003268/logging-interceptor-4.9.3.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/logging-interceptor/4.9.3/d5e9086da6f45de1ddbbd89c62288d921d5e7d87/logging-interceptor-4.9.3-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/logging-interceptor/4.9.3/30288bd77d2f72d76d30688be15ecb7909272dcf/logging-interceptor-4.9.3-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_okhttp3_okhttp_4_11_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup.okhttp3:okhttp:4.11.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/4.11.0/436932d695b2c43f2c86b8111c596179cd133d56/okhttp-4.11.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/4.11.0/c5d91892aa84d5a6a9a3367b640607d9524974cd/okhttp-4.11.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/4.11.0/9bfc7526f84edf546cf34aaf23bdbc2b30147c34/okhttp-4.11.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_okio_okio_jvm_3_5_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup.okio:okio-jvm:3.5.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio-jvm/3.5.0/d6a0bc7343210eff7dd5cfdd6eb9b5f0036638ce/okio-jvm-3.5.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio-jvm/3.5.0/8d8b4bb3fdd95e9263527aa0874edc88a415aec2/okio-jvm-3.5.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio-jvm/3.5.0/c29d303c0329c9bbcf32b4ab23cb73a683b65c63/okio-jvm-3.5.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_retrofit2_converter_moshi_2_9_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup.retrofit2:converter-moshi:2.9.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/converter-moshi/2.9.0/db0979801926e6d39bc2478736145f9761c3e034/converter-moshi-2.9.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/converter-moshi/2.9.0/cf43081e493a6eec8e9c22e4c22790ed2ee24efc/converter-moshi-2.9.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/converter-moshi/2.9.0/274e84654aca7c92d957aaeae21382e192a49a8/converter-moshi-2.9.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__com_squareup_retrofit2_retrofit_2_9_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: com.squareup.retrofit2:retrofit:2.9.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/retrofit/2.9.0/d8fdfbd5da952141a665a403348b74538efc05ff/retrofit-2.9.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/retrofit/2.9.0/920d425bcf21e948cf071783e9a0badbfd880fac/retrofit-2.9.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.retrofit2/retrofit/2.9.0/409e80ce46c84ef7e74b6934032a73b8421eebe5/retrofit-2.9.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__dev_chrisbanes_snapper_snapper_0_2_2_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: dev.chrisbanes.snapper:snapper:0.2.2@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/1d1c3abd54beded12e26d1a666f7ff52/transformed/snapper-0.2.2/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/1d1c3abd54beded12e26d1a666f7ff52/transformed/snapper-0.2.2/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/dev.chrisbanes.snapper/snapper/0.2.2/ba580677251df23f37fb3868f735bb558a35295e/snapper-0.2.2-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/dev.chrisbanes.snapper/snapper/0.2.2/79ea850ac50acaded6291071ddc09cb99bda2de7/snapper-0.2.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__io_coil_kt_coil_2_4_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: io.coil-kt:coil:2.4.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/10bc782c90ed5659eaf18666f1beeebe/transformed/coil-2.4.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/10bc782c90ed5659eaf18666f1beeebe/transformed/coil-2.4.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil/2.4.0/3aad135d2d33b3a7792cd093b7bb830e5ae23462/coil-2.4.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil/2.4.0/937a2d5a82528330e0a0c6b09142703a4a0874ae/coil-2.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__io_coil_kt_coil_base_2_4_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: io.coil-kt:coil-base:2.4.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/251cd051eb5a71fa0254dcba751603d4/transformed/coil-base-2.4.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/251cd051eb5a71fa0254dcba751603d4/transformed/coil-base-2.4.0/AndroidManifest.xml\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/251cd051eb5a71fa0254dcba751603d4/transformed/coil-base-2.4.0/res\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil-base/2.4.0/e62d4c51a989af21b68e5bba567284a984b8be23/coil-base-2.4.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil-base/2.4.0/468367786455e03d919153ad895fc6d84c24fac1/coil-base-2.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__io_coil_kt_coil_compose_2_4_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: io.coil-kt:coil-compose:2.4.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/998256d739d3e0fd29311e911f6930b2/transformed/coil-compose-2.4.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/998256d739d3e0fd29311e911f6930b2/transformed/coil-compose-2.4.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil-compose/2.4.0/cd662105b1f3272435a49b99bddfa551b1cbe10e/coil-compose-2.4.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil-compose/2.4.0/399ab6cad43ebc28b3e06a437df8928805c3b51b/coil-compose-2.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__io_coil_kt_coil_compose_base_2_4_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: io.coil-kt:coil-compose-base:2.4.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ba6273637bb039509fecbba21401c2af/transformed/coil-compose-base-2.4.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ba6273637bb039509fecbba21401c2af/transformed/coil-compose-base-2.4.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil-compose-base/2.4.0/1f984abcfe62f51ec7ad927f26c06af3be51eab5/coil-compose-base-2.4.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.coil-kt/coil-compose-base/2.4.0/e4d05f796877709d9a26cd7f4ec53f96ec4cc868/coil-compose-base-2.4.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__io_github_fornewid_material_motion_compose_core_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: io.github.fornewid:material-motion-compose-core:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/ec365c0cb3da64c5d2642532588aef86/transformed/material-motion-compose-core-1.1.0/AndroidManifest.xml\" />\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/ec365c0cb3da64c5d2642532588aef86/transformed/material-motion-compose-core-1.1.0/jars/classes.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.github.fornewid/material-motion-compose-core/1.1.0/3fa4756831a0755e014067f5053d79a12cc3911/material-motion-compose-core-1.1.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.github.fornewid/material-motion-compose-core/1.1.0/d2ef7346bd521b742e64069cc849dec60ea7c11/material-motion-compose-core-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__io_github_fornewid_material_motion_compose_navigation_1_1_0_aar.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: io.github.fornewid:material-motion-compose-navigation:1.1.0@aar\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/transforms-3/413aaef63ea95ae0022ef8d3418ce53a/transformed/material-motion-compose-navigation-1.1.0/jars/classes.jar!/\" />\n      <root url=\"file://$USER_HOME$/.gradle/caches/transforms-3/413aaef63ea95ae0022ef8d3418ce53a/transformed/material-motion-compose-navigation-1.1.0/AndroidManifest.xml\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.github.fornewid/material-motion-compose-navigation/1.1.0/5d912ecf719cca185f1e6400e46c8c63857d28b8/material-motion-compose-navigation-1.1.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.github.fornewid/material-motion-compose-navigation/1.1.0/69259c348f6ead3beffda4189dbea5d17d07779a/material-motion-compose-navigation-1.1.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__javax_inject_javax_inject_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: javax.inject:javax.inject:1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/6975da39a7040257bd51d21a231b76c915872d38/javax.inject-1.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/70ec961c25111ed9015d1af77772d96383c2d238/javax.inject-1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.inject/javax.inject/1/a00123f261762a7c5e0ec916a2c7c8298d29c400/javax.inject-1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__junit_junit_4_13_2.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: junit:junit:4.13.2\" external-system-id=\"GRADLE\">\n    <ANNOTATIONS>\n      <root url=\"jar://$USER_HOME$/.m2/repository/org/jetbrains/externalAnnotations/junit/junit/4.12-an1/junit-4.12-an1-annotations.zip!/\" />\n    </ANNOTATIONS>\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.13.2/8ac9e16d933b6fb43bc7f576336b8f4d7eb5ba12/junit-4.13.2.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.13.2/f2f3f384dacd2ade2ddf7aa7e0f4360dfee38672/junit-4.13.2-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.13.2/33987872a811fe4d4001ed494b07854822257f42/junit-4.13.2-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.hamcrest:hamcrest-core:1.3\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/ad09811315f1d4f5756986575b0ea16b99cd686f/hamcrest-core-1.3-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.hamcrest:hamcrest-integration:1.3\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-integration/1.3/5de0c73fef18917cd85d0ab70bb23818685e4dfd/hamcrest-integration-1.3.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-integration/1.3/cc5884d4138d3376f574f6a3992acceedfc37bea/hamcrest-integration-1.3-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-integration/1.3/ae7787a563e6a1b1f17fd4ac43be3a3c8830cfda/hamcrest-integration-1.3-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.hamcrest:hamcrest-library:1.3\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-library/1.3/4785a3c21320980282f9f33d0d1264a69040538f/hamcrest-library-1.3.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-library/1.3/4324046c5f99f3dc91b5370899fa3ae65fd137d2/hamcrest-library-1.3-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-library/1.3/47a7ee46628ab7133129cd7cef1e92657bc275e/hamcrest-library-1.3-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_annotations_23_0_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains:annotations:23.0.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/23.0.0/8cc20c07506ec18e0834947b84a864bfc094484e/annotations-23.0.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/23.0.0/41442a550d78cb59a601c1d38603f6ab5497f93c/annotations-23.0.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/23.0.0/ca5088d615accaabd2aa956b10b236a4e75cfccb/annotations-23.0.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_android_extensions_runtime_1_9_22.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.22\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"org.jetbrains.kotlin\" artifactId=\"kotlin-android-extensions-runtime\" version=\"1.9.22\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-android-extensions-runtime/1.9.22/ee3bc0c3b55cb516ac92d6a093e1b939166b86a2/kotlin-android-extensions-runtime-1.9.22.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-android-extensions-runtime/1.9.22/2ad14aed781c4a73ed4dbb421966d408a0a06686/kotlin-android-extensions-runtime-1.9.22-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-android-extensions-runtime/1.9.22/b4ffa2ce90411e440d2fdeb43be0dc1d5d133551/kotlin-android-extensions-runtime-1.9.22-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_parcelize_runtime_1_9_22.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"org.jetbrains.kotlin\" artifactId=\"kotlin-parcelize-runtime\" version=\"1.9.22\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-parcelize-runtime/1.9.22/de4a21d6560cadd035c69ba3af3ad1afecc95299/kotlin-parcelize-runtime-1.9.22.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-parcelize-runtime/1.9.22/2ad14aed781c4a73ed4dbb421966d408a0a06686/kotlin-parcelize-runtime-1.9.22-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-parcelize-runtime/1.9.22/178dc7db4a2f72f3b64b528c680dddd48ecf9adf/kotlin-parcelize-runtime-1.9.22-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_reflect_1_8_21.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlin:kotlin-reflect:1.8.21\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.8.21/662838019bc1141f8a311180d93b9e13765c7f55/kotlin-reflect-1.8.21.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.8.21/5b8f86fea035328fc9e8c660773037a3401ce25f/kotlin-reflect-1.8.21-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.8.21/b0e90795b7693974af8abac3f1b97ffc3cf00916/kotlin-reflect-1.8.21-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_reflect_1_8_22.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlin:kotlin-reflect:1.8.22\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.8.22/b52be44bc57cb6fd2169a29aefa4507c4e49c858/kotlin-reflect-1.8.22.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.8.22/5b8f86fea035328fc9e8c660773037a3401ce25f/kotlin-reflect-1.8.22-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.8.22/b0e90795b7693974af8abac3f1b97ffc3cf00916/kotlin-reflect-1.8.22-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_9_22.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.9.22\" type=\"java-imported\" external-system-id=\"GRADLE\">\n    <properties groupId=\"org.jetbrains.kotlin\" artifactId=\"kotlin-stdlib\" version=\"1.9.22\" />\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.22/d6c44cd08d8f3f9bece8101216dbe6553365c6e3/kotlin-stdlib-1.9.22.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.22/2ad14aed781c4a73ed4dbb421966d408a0a06686/kotlin-stdlib-1.9.22-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.22/d1b45176c0aeb15a309a4f4a7cd160d4b3c8b733/kotlin-stdlib-1.9.22-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk7_1_9_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.0/f320478990d05e0cfaadd74f9619fd6027adbf37/kotlin-stdlib-jdk7-1.9.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.0/5b8f86fea035328fc9e8c660773037a3401ce25f/kotlin-stdlib-jdk7-1.9.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.0/3641d7cb7650db9fe93a5361b1b88cbcefdb01e0/kotlin-stdlib-jdk7-1.9.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_jdk8_1_9_0.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.0/e000bd084353d84c9e888f6fb341dc1f5b79d948/kotlin-stdlib-jdk8-1.9.0.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.0/5b8f86fea035328fc9e8c660773037a3401ce25f/kotlin-stdlib-jdk8-1.9.0-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.0/20739e7aae2a2bfb66c4081b233ffea7b947cf77/kotlin-stdlib-jdk8-1.9.0-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlinx_kotlinx_coroutines_android_1_7_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-android/1.7.1/c2d86b569f10b7fc7e28d3f50c0eed97897d77a7/kotlinx-coroutines-android-1.7.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-android/1.7.1/b62319163f9052b8a959ebd62d7bb81bb309a0ee/kotlinx-coroutines-android-1.7.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-android/1.7.1/d43e33a7c7ee4bdb6fb3210bfdffee23f275e3dc/kotlinx-coroutines-android-1.7.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "path": ".idea/libraries/Gradle__org_jetbrains_kotlinx_kotlinx_coroutines_core_jvm_1_7_1.xml",
    "content": "<component name=\"libraryTable\">\n  <library name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.1\" external-system-id=\"GRADLE\">\n    <CLASSES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.7.1/63a0779cf668e2a47d13fda7c3b0c4f8dc7762f4/kotlinx-coroutines-core-jvm-1.7.1.jar!/\" />\n    </CLASSES>\n    <JAVADOC>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.7.1/e653e51cc736c8e47cd9a62080f4adfce8330614/kotlinx-coroutines-core-jvm-1.7.1-javadoc.jar!/\" />\n    </JAVADOC>\n    <SOURCES>\n      <root url=\"jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.7.1/9ba46d8eb284ab4db835daebb561d8e5e918467e/kotlinx-coroutines-core-jvm-1.7.1-sources.jar!/\" />\n    </SOURCES>\n  </library>\n</component>"
  },
  {
    "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": "<project version=\"4\">\n  <component name=\"DesignSurface\">\n    <option name=\"filePathToZoomLevelMap\">\n      <map>\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_arrow_back.xml\" value=\"0.2775\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_look_more.xml\" value=\"0.2775\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_manga_7day.xml\" value=\"0.213\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_manga_history.xml\" value=\"0.213\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_manga_info_main.xml\" value=\"0.213\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_manga_login.xml\" value=\"0.213\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_manga_next_dark.xml\" value=\"0.255\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_manga_next_light.xml\" value=\"0.255\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-anydpi/ic_manga_search.xml\" value=\"0.213\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable-v24/ic_launcher_foreground.xml\" value=\"0.2205\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/drawable/ic_launcher_background.xml\" value=\"0.2205\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/activity_main.xml\" value=\"0.25\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/bottom_tab.xml\" value=\"0.2\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/categories_item.xml\" value=\"0.3591485507246377\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/chip.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/chip_1.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/fragment_rank.xml\" value=\"0.5\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/hot_manga_layout.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/input_layout.xml\" value=\"0.2\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/layout_manga_detail.xml\" value=\"0.264\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/layout_manga_list_item.xml\" value=\"0.2\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/layout_manga_rank_back.xml\" value=\"0.3591485507246377\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/layout_rank_manga_detail.xml\" value=\"0.335\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/list_chapter.xml\" value=\"0.23157894736842105\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/list_popup_window_item.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/main_page_in.xml\" value=\"0.11527777777777778\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_banner_mian.xml\" value=\"0.25\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_card_detail_view.xml\" value=\"0.22894736842105262\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_headline_1.xml\" value=\"0.25\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_headline_2.xml\" value=\"0.25\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_history.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_history_in.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_info.xml\" value=\"0.2\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_list.xml\" value=\"0.2\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_reader_fragment.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/manga_reader_layout.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/persional_data.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/persional_data_in.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/personal_data_in.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/rank_manga_fragment.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/rank_manga_layout.xml\" value=\"0.176\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/search_tab.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/layout/sort_tab.xml\" value=\"0.2\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/menu/menu_main.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/menu/menu_search_layout.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/menu/rank_bottom_item.xml\" value=\"0.15756578947368421\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml\" value=\"0.2205\" />\n        <entry key=\"..\\:/Users/ShihCheeng/AndroidStudioProjects/CopyMangaJava/app/src/main/res/mipmap-anydpi-v26/ic_launcher_copy.xml\" value=\"0.2205\" />\n      </map>\n    </option>\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_17\" default=\"true\" project-jdk-name=\"jbr-17\" 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/modules/CopyMangaJava.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\"CopyMangaJava\" external.linked.project.path=\"$MODULE_DIR$/../..\" external.root.project.path=\"$MODULE_DIR$/../..\" external.system.id=\"GRADLE\" external.system.module.group=\"\" external.system.module.version=\"unspecified\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\" inherit-compiler-output=\"true\">\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$/../..\">\n      <excludeFolder url=\"file://$MODULE_DIR$/../../.gradle\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/../../build\" />\n    </content>\n    <orderEntry type=\"inheritedJdk\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n  </component>\n</module>"
  },
  {
    "path": ".idea/modules/app/CopyMangaJava.app.androidTest.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":app:androidTest\" external.linked.project.path=\"$MODULE_DIR$/../../../app\" external.root.project.path=\"$MODULE_DIR$/../../..\" external.system.id=\"GRADLE\" external.system.module.type=\"sourceSet\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet external-system-id=\"GRADLE\" type=\"kotlin-language\" name=\"Kotlin\">\n      <configuration version=\"5\" platform=\"JVM 17\" allPlatforms=\"JVM [17]\" useProjectSettings=\"false\">\n        <additionalVisibleModuleNames>:app:main</additionalVisibleModuleNames>\n        <compilerSettings />\n        <compilerArguments>\n          <flagArguments>\n            <flagArg name=\"allowNoSourceFiles\" arg=\"true\" />\n            <flagArg name=\"allowUnstableDependencies\" arg=\"true\" />\n            <flagArg name=\"noReflect\" arg=\"true\" />\n            <flagArg name=\"noStdlib\" arg=\"true\" />\n          </flagArguments>\n          <stringArguments>\n            <stringArg name=\"destination\" arg=\"$MODULE_DIR$/../../../app/build/tmp/kotlin-classes/debugAndroidTest\" />\n            <stringArg name=\"jvmTarget\" arg=\"17\" />\n            <stringArg name=\"moduleName\" arg=\"app_debugAndroidTest\" />\n            <stringArg name=\"apiVersion\" arg=\"1.9\" />\n            <stringArg name=\"languageVersion\" arg=\"1.9\" />\n          </stringArguments>\n          <arrayArguments>\n            <arrayArg name=\"pluginClasspaths\">\n              <args>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-parcelize-compiler/1.9.22/222c989e288e9a99c8579de44a0fe61230ddbfc5/kotlin-parcelize-compiler-1.9.22.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.devtools.ksp/symbol-processing/1.9.22-1.0.16/70b84dfb906092d3995f07ab28b24390f7547ae3/symbol-processing-1.9.22-1.0.16.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embeddable/1.9.22/9cd4dc7773cf2a99ecd961a88fbbc9a2da3fb5e1/kotlin-compiler-embeddable-1.9.22.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.devtools.ksp/symbol-processing-api/1.9.22-1.0.16/ca56365e65965a5b9b4a6da4597221e22604ff34/symbol-processing-api-1.9.22-1.0.16.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.0/e000bd084353d84c9e888f6fb341dc1f5b79d948/kotlin-stdlib-jdk8-1.9.0.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.0/f320478990d05e0cfaadd74f9619fd6027adbf37/kotlin-stdlib-jdk7-1.9.0.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.22/d6c44cd08d8f3f9bece8101216dbe6553365c6e3/kotlin-stdlib-1.9.22.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.9.22/f8139a46fc677ec9badc49ae954392f4f5e7e7c7/kotlin-script-runtime-1.9.22.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.6.10/1cbe9c92c12a94eea200d23c2bbaedaf3daf5132/kotlin-reflect-1.6.10.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-daemon-embeddable/1.9.22/20e2c5df715f3240c765cfc222530e2796542021/kotlin-daemon-embeddable-1.9.22.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.intellij.deps/trove4j/1.0.20200330/3afb14d5f9ceb459d724e907a21145e8ff394f02/trove4j-1.0.20200330.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar</arg>\n                <arg>$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.compiler/compiler/1.5.8/b6b82a47735d855ae7050d1aa2f026dfeedaf635/compiler-1.5.8.jar</arg>\n              </args>\n            </arrayArg>\n            <arrayArg name=\"pluginOptions\">\n              <args>\n                <arg>plugin:androidx.compose.plugins.idea:enabled=true</arg>\n                <arg>plugin:androidx.compose.compiler.plugins.kotlin:sourceInformation=true</arg>\n              </args>\n            </arrayArg>\n          </arrayArguments>\n        </compilerArguments>\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"\" />\n        <option name=\"TEST_RES_FOLDERS_RELATIVE_PATH\" value=\"file://$MODULE_DIR$/../../../app/src/androidTest/res;file://$MODULE_DIR$/../../../app/src/androidTestDebug/res;file://$MODULE_DIR$/../../../app/build/generated/res/resValues/androidTest/debug\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_17\">\n    <output-test url=\"file://$MODULE_DIR$/../../../app/build/intermediates/javac/debugAndroidTest/classes\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debugAndroidTest/out\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debugAndroidTest/out\" isTestSource=\"true\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debugAndroidTest/java\" />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debugAndroidTest/kotlin\" />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/res/resValues/androidTest/debug\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/res/resValues/androidTest/debug\" type=\"java-test-resource\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/androidTest/debug\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debugAndroidTest\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debugAndroidTest\" isTestSource=\"true\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kaptKotlin/debugAndroidTest\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kaptKotlin/debugAndroidTest\" isTestSource=\"true\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/src/androidTest\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/src/androidTest/java\" isTestSource=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/src/androidTestDebug\" />\n    <orderEntry type=\"jdk\" jdkName=\"Android API 34, extension level 7 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"module\" module-name=\"CopyMangaJava.app.main\" scope=\"TEST\" />\n    <orderEntry type=\"module-library\" scope=\"TEST\">\n      <library name=\"Gradle: kaptGeneratedClasses\">\n        <CLASSES>\n          <root url=\"file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debugAndroidTest\" />\n        </CLASSES>\n        <JAVADOC />\n        <SOURCES />\n      </library>\n    </orderEntry>\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-testing:2.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-runtime:2.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.sqlite:sqlite:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.sqlite:sqlite-framework:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test.ext:junit:1.1.5@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test:core:1.5.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test:monitor:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test:annotation:1.0.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.annotation:annotation-experimental:1.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.tracing:tracing:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test.services:storage:1.4.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test.espresso:espresso-core:3.5.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test:runner:1.5.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test.espresso:espresso-idling-resource:3.5.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.databinding:viewbinding:8.2.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment-testing:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment-ktx:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.activity:activity-ktx:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.activity:activity:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.core:core:1.12.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-runtime:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.versionedparcelable:versionedparcelable:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.core:core-ktx:1.12.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.savedstate:savedstate:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-runtime-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.savedstate:savedstate-ktx:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.loader:loader:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.arch.core:core-runtime:2.2.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.viewpager:viewpager:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.customview:customview:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment-testing-manifest:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.appcompat:appcompat:1.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.appcompat:appcompat-resources:1.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.vectordrawable:vectordrawable:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.vectordrawable:vectordrawable-animated:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.interpolator:interpolator:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.cursoradapter:cursoradapter:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.drawerlayout:drawerlayout:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.android.material:material:1.11.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.cardview:cardview:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.coordinatorlayout:coordinatorlayout:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.constraintlayout:constraintlayout:2.1.4@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.dynamicanimation:dynamicanimation:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.legacy:legacy-support-core-utils:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.documentfile:documentfile:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.localbroadcastmanager:localbroadcastmanager:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.print:print:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.recyclerview:recyclerview:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.transition:transition:1.2.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.viewpager2:viewpager2:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.KotatsuApp:subsampling-scale-image-view:1b19231b2f@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:glide:4.15.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:gifdecoder:4.15.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.exifinterface:exifinterface:1.3.3@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-process:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.startup:startup-runtime:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.runtime:runtime-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.runtime:runtime-saveable-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-geometry-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-graphics-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-unit-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-text-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-util-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-service:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.palette:palette-ktx:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.palette:palette:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.solkin:disk-lru-cache:1.4@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-fragment-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-fragment:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-runtime:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-common:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.slidingpanelayout:slidingpanelayout:1.2.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-runtime-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-common-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-ui-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-ui:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-runtime-ktx:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-runtime:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-ktx:2.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.mikepenz:aboutlibraries-core-android-debug:10.5.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.mikepenz:aboutlibraries:10.5.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.work:work-runtime-ktx:2.9.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.work:work-runtime:2.9.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-work:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:hilt-android:2.48.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:dagger-lint-aar:2.48.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.preference:preference-ktx:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.preference:preference:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material3:material3-android:1.2.0-rc01@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.foundation:foundation-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.animation:animation-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.animation:animation-core-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.foundation:foundation-layout-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material:material-icons-core-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material:material-ripple-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.accompanist:accompanist-themeadapter-material3:0.33.1-alpha@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-tooling-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-tooling-data-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-tooling-preview-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.activity:activity-compose:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.accompanist:accompanist-pager-indicators:0.31.3-beta@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.accompanist:accompanist-pager:0.31.3-beta@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: dev.chrisbanes.snapper:snapper:0.2.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material:material-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-compose:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-compose:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.animation:animation-graphics-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.github.fornewid:material-motion-compose-navigation:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.github.fornewid:material-motion-compose-core:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil-base:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil-compose:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil-compose-base:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-navigation-compose:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-navigation:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-common:2.6.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.annotation:annotation-jvm:1.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains:annotations:23.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-migration:2.6.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: junit:junit:4.13.2\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.hamcrest:hamcrest-core:1.3\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.code.findbugs:jsr305:3.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-common:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.guava:listenablefuture:1.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.concurrent:concurrent-futures:1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup:javawriter:2.1.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: javax.inject:javax.inject:1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.hamcrest:hamcrest-library:1.3\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.hamcrest:hamcrest-integration:1.3\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.arch.core:core-common:2.2.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.collection:collection-jvm:1.4.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.collection:collection-ktx:1.4.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.resourceinspection:resourceinspection-annotation:1.0.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.code.gson:gson:2.10.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.okhttp3:okhttp:4.11.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.okio:okio-jvm:3.5.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.okhttp3:logging-interceptor:4.9.3\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:disklrucache:4.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:annotations:4.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-common-java8:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-common:3.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-common-ktx:3.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-common:1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:dagger:2.48.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:hilt-core:2.48.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.retrofit2:retrofit:2.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.retrofit2:converter-moshi:2.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.moshi:moshi:1.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.moshi:moshi-kotlin:1.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-reflect:1.8.21\" level=\"project\" />\n  </component>\n  <component name=\"TestModuleProperties\" production-module=\"CopyMangaJava.app.main\" />\n</module>"
  },
  {
    "path": ".idea/modules/app/CopyMangaJava.app.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":app\" external.linked.project.path=\"$MODULE_DIR$/../../../app\" external.root.project.path=\"$MODULE_DIR$/../../..\" external.system.id=\"GRADLE\" external.system.module.group=\"CopyMangaJava\" external.system.module.version=\"unspecified\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"android-gradle\" name=\"Android-Gradle\">\n      <configuration>\n        <option name=\"LAST_SUCCESSFUL_SYNC_AGP_VERSION\" value=\"8.2.2\" />\n        <option name=\"LAST_KNOWN_AGP_VERSION\" value=\"8.2.2\" />\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"\" />\n        <option name=\"TEST_RES_FOLDERS_RELATIVE_PATH\" value=\"\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n      </configuration>\n    </facet>\n    <facet type=\"kotlin-language\" name=\"Kotlin\">\n      <configuration version=\"4\" platform=\"JVM 1.8\" allPlatforms=\"JVM [1.8]\" useProjectSettings=\"false\">\n        <compilerSettings>\n          <option name=\"additionalArguments\" value=\"-Xallow-no-source-files\" />\n        </compilerSettings>\n        <compilerArguments>\n          <option name=\"destination\" value=\"$MODULE_DIR$/../../../app/build/tmp/kotlin-classes/debug\" />\n          <option name=\"classpath\" value=\"$MODULE_DIR$/../../../app/build/intermediates/compile_and_runtime_not_namespaced_r_class_jar/debug/R.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/logging-interceptor/4.9.3/d7786efea637a62603352985d9a229c206003268/logging-interceptor-4.9.3.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/ec56f2e09c0da0b2743bd927c654c308/transformed/lifecycle-viewmodel-compose-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/90099cb65649f4c13cfb8857c971161f/transformed/fragment-ktx-1.4.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/2c17cd3ff9349604f0e9087a13318f7a/transformed/activity-ktx-1.4.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/ee9b33831fa497020b7891225513de24/transformed/lifecycle-viewmodel-ktx-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/3bba435f0da5876844b5ba78ca53eca2/transformed/room-ktx-2.4.2-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/879db3531981ca6bdabc984407ca250b/transformed/ui-1.0.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/aa6ae0458cfa6bd22f652c319a7da59c/transformed/runtime-saveable-1.0.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/fe34192e866bc7e1608cc2e1c6a57388/transformed/runtime-1.0.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/52f06dd006197cb6fa87c94f850f66a9/transformed/about-2.5.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/de79cf153d99390dbd7da37afae7a77f/transformed/material-1.7.0-alpha01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/139c0a65cdf1e91f420ad01ef91eddb8/transformed/subsampling-scale-image-view-androidx-3.10.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/731e2018f2f213fa6868e0f8db0aa858/transformed/appcompat-1.4.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/494a67b9e5d2ca5852a0664e545b8e2e/transformed/glide-4.13.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/2b519da702081d69b3d6a89fc05f974c/transformed/viewpager2-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/f58836572425ddf07fca315585f27231/transformed/fragment-1.4.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/af188b424fc4185fd5ff5fd213a0a155/transformed/activity-1.4.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/2965af4d52ecd7689d04f7c10f3cf022/transformed/lifecycle-viewmodel-savedstate-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/cca902857258a7c0d422ae743fa4a711/transformed/lifecycle-runtime-ktx-2.3.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/93b321497c36961191d21de82593d732/transformed/lifecycle-livedata-ktx-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.6.0/f3b8fd26c2e76d2f18cbc36aacb6e349fcb9fd5f/kotlinx-coroutines-core-jvm-1.6.0.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-android/1.6.0/453fa53456bbaea50e51bd92d7f16f7bf6fcc58e/kotlinx-coroutines-android-1.6.0.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.6.21/eeb4d60d75e9ea9c11200d52974e522793b14fba/kotlin-stdlib-jdk8-1.6.21.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/636232e0a3b13119687630648f48bac8/transformed/multitype-4.3.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/4.9.3/b0b14b3d12980912723fb8b66afb48dcda742fcb/okhttp-4.9.3.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.6.21/568c1b78a8e17a4f35b31f0a74e2916095ed74c2/kotlin-stdlib-jdk7-1.6.21.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/2.8.0/49b64e09d81c0cc84b267edd0c2fd7df5a64c78c/okio-jvm-2.8.0.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/32c40988a1e78a08852ecb45697a3ea9/transformed/palette-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/ac553c428bd06da26025eb932e2a2625/transformed/dynamicanimation-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/4f9926fcd611b6b93f5bc8aa190b5e63/transformed/legacy-support-core-utils-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/38a6961c50023249958db08fa0018d1b/transformed/loader-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/e5eca9d85a64546ba6771ae899537821/transformed/lifecycle-viewmodel-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/503ed6b97e59d1542be9c962dc217da8/transformed/lifecycle-livedata-core-ktx-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/06a4adbe5a9da76a714a90a3075fc12b/transformed/savedstate-ktx-1.1.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/736e8373b407a15976ab3774c41a44d1/transformed/savedstate-1.2.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/473b2d074dd1abb7ce674d19b9a77173/transformed/core-ktx-1.2.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/androidx.collection/collection-ktx/1.1.0/f807b2f366f7b75142a67d2f3c10031065b5168/collection-ktx-1.1.0.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.6.21/11ef67f1900634fd951bad28c53ec957fabbe5b8/kotlin-stdlib-1.6.21.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.6.21/5e5b55c26dbc80372a920aef60eb774b714559b8/kotlin-stdlib-common-1.6.21.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/16fc3193c397b09135ef02f778698400/transformed/appcompat-resources-1.4.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/7a0963ea5908efbae83fe1fadab2e5c9/transformed/drawerlayout-1.1.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/6df37f00680fe2a1bdcc65662db1b529/transformed/coordinatorlayout-1.1.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/d750116d5f3fecb4e0ec812d1c04fe99/transformed/recyclerview-1.2.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/03f228edc98e40cbdc7fbf1bc25a111f/transformed/transition-1.2.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/02f817cb909ecb7d835bd70ac7aa2173/transformed/vectordrawable-animated-1.1.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/b0c6448455b87889aef88a02e1abc6ff/transformed/vectordrawable-1.1.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/a4f472789ea00fc3b206fa2e53bd7e7e/transformed/viewpager-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/cd57672d5a62584c91294f845241064e/transformed/customview-1.1.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/e44d90ce1326d0789fc77d0315986c95/transformed/core-1.7.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/be128eb35ed886838fbb4c6d51c22243/transformed/cursoradapter-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/cc887cd7b62f76fed7b33fe582395e72/transformed/cardview-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/ecf5265aaffcdf4b184183b1437d0cbe/transformed/lifecycle-runtime-2.4.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/c8955d622cabe04df8a0b004b267688a/transformed/exifinterface-1.2.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/cea6c1b1f25b045e71c34016af04ac3c/transformed/gifdecoder-4.13.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common-java8/2.5.0-beta01/5b8f86fea035328fc9e8c660773037a3401ce25f/lifecycle-common-java8-2.5.0-beta01.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/162f23699f4fd5a1fb2e6a327bfcf318/transformed/room-runtime-2.4.2-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/androidx.room/room-common/2.4.2/63d9f9cb245ee9b4c8ebb8aca201661f99583ffa/room-common-2.4.2.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/fa620dc8352e498452cbd95f52b10483/transformed/versionedparcelable-1.1.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/androidx.collection/collection/1.1.0/1f27220b47669781457de0d600849a5de0e89909/collection-1.1.0.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/fbb790f8f39f1c34c8113792f0654976/transformed/lifecycle-livedata-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/980bba5d64fc06231b7d905092ecf1e4/transformed/lifecycle-livedata-core-2.5.0-beta01-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common/2.5.0-beta01/1fdb7349701e9cf2f0a69fc10642b6fef6bb3e12/lifecycle-common-2.5.0-beta01.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/97e3873c61851fa3247bc671a66c8075/transformed/core-runtime-2.1.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/androidx.arch.core/core-common/2.1.0/b3152fc64428c9354344bd89848ecddc09b6f07e/core-common-2.1.0.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/9aa3f025a4069b80421372eef6f95cb3/transformed/interpolator-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/b36d4857beec0676209e700cb72807b0/transformed/ui-text-1.0.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/22e4b4aefb984413120ae04e82808531/transformed/ui-graphics-1.0.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/0bfcee4294059a1052b43fc23801405f/transformed/ui-unit-1.0.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/f93cb38a656d69eecca23d9ec6ea44ed/transformed/ui-geometry-1.0.1-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/a4777d08178faaeb0228616197c5fa1b/transformed/documentfile-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/0f9820c18987fa72993d669816e1cb28/transformed/localbroadcastmanager-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/46da752fca649ecbc208ae0021e0127b/transformed/print-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/a3d537c47beacce73f63d296beea750a/transformed/sqlite-framework-2.2.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/1ef1cd6723843dbda4e521b98d4eca0a/transformed/sqlite-2.2.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/androidx.annotation/annotation/1.3.0/21f49f5f9b85fc49de712539f79123119740595/annotation-1.3.0.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/65a1c601703f4e608ed92b23f887c39f/transformed/annotation-experimental-1.1.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/e53646c36e0dc215f5c6730b709d0278/transformed/tracing-1.0.0-api.jar;C:/Users/ShihCheeng/.gradle/caches/transforms-3/123241ad080e77435957b6db6b7bc4ca/transformed/constraintlayout-2.1.3-api.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.9.0/8a1167e089096758b49f9b34066ef98b2f4b37aa/gson-2.9.0.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/disklrucache/4.13.1/a0f36f127647088ee0373cb871409755e4c32834/disklrucache-4.13.1.jar;C:/Users/ShihCheeng/.gradle/caches/modules-2/files-2.1/com.github.bumptech.glide/annotations/4.13.1/26fa2ae721524d54a83c623c3a151a65f0aefbaf/annotations-4.13.1.jar;C:/Users/ShihCheeng/AppData/Local/Android/Sdk/platforms/android-32/android.jar;C:/Users/ShihCheeng/AppData/Local/Android/Sdk/build-tools/30.0.3/core-lambda-stubs.jar\" />\n          <option name=\"noStdlib\" value=\"true\" />\n          <option name=\"moduleName\" value=\"app_debug\" />\n          <option name=\"jvmTarget\" value=\"1.8\" />\n          <option name=\"languageVersion\" value=\"1.6\" />\n          <option name=\"apiVersion\" value=\"1.6\" />\n          <option name=\"pluginClasspaths\">\n            <array>\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embeddable/1.6.21/97bdd5a752ce73b58ef16c17bc7f0ea2faff7a2e/kotlin-compiler-embeddable-1.6.21.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.6.21/5dc3574d9b7bebfcb4ec6b10ada4aaa9e140bd0b/kotlin-reflect-1.6.21.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.6.21/11ef67f1900634fd951bad28c53ec957fabbe5b8/kotlin-stdlib-1.6.21.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.6.21/5e5b55c26dbc80372a920aef60eb774b714559b8/kotlin-stdlib-common-1.6.21.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.6.21/99c6675100da5d6d5b1c5a1032f27f28008d101b/kotlin-script-runtime-1.6.21.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-daemon-embeddable/1.6.21/46b78cf392e1c4f10854c3cadba44abb7b82250f/kotlin-daemon-embeddable-1.6.21.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.intellij.deps/trove4j/1.0.20200330/3afb14d5f9ceb459d724e907a21145e8ff394f02/trove4j-1.0.20200330.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna/5.6.0/330f2244e9030119ab3030fc3fededc86713d9cc/jna-5.6.0.jar\" />\n            </array>\n          </option>\n          <option name=\"pluginOptions\">\n            <array />\n          </option>\n        </compilerArguments>\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_17\">\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$/../../../app\">\n      <excludeFolder url=\"file://$MODULE_DIR$/../../../app/.gradle\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/../../../app/build\" />\n    </content>\n    <orderEntry type=\"jdk\" jdkName=\"Android API 34, extension level 7 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n  </component>\n</module>"
  },
  {
    "path": ".idea/modules/app/CopyMangaJava.app.main.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":app:main\" external.linked.project.path=\"$MODULE_DIR$/../../../app\" external.root.project.path=\"$MODULE_DIR$/../../..\" external.system.id=\"GRADLE\" external.system.module.type=\"sourceSet\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet external-system-id=\"GRADLE\" type=\"kotlin-language\" name=\"Kotlin\">\n      <configuration version=\"4\" platform=\"JVM 17\" allPlatforms=\"JVM [17]\" useProjectSettings=\"false\">\n        <compilerSettings />\n        <compilerArguments>\n          <option name=\"destination\" value=\"$MODULE_DIR$/../../../app/build/tmp/kotlin-classes/debug\" />\n          <option name=\"noStdlib\" value=\"true\" />\n          <option name=\"noReflect\" value=\"true\" />\n          <option name=\"moduleName\" value=\"app_debug\" />\n          <option name=\"jvmTarget\" value=\"17\" />\n          <option name=\"allowUnstableDependencies\" value=\"true\" />\n          <option name=\"allowNoSourceFiles\" value=\"true\" />\n          <option name=\"languageVersion\" value=\"1.9\" />\n          <option name=\"apiVersion\" value=\"1.9\" />\n          <option name=\"pluginClasspaths\">\n            <array>\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-parcelize-compiler/1.9.22/222c989e288e9a99c8579de44a0fe61230ddbfc5/kotlin-parcelize-compiler-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.devtools.ksp/symbol-processing/1.9.22-1.0.16/70b84dfb906092d3995f07ab28b24390f7547ae3/symbol-processing-1.9.22-1.0.16.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embeddable/1.9.22/9cd4dc7773cf2a99ecd961a88fbbc9a2da3fb5e1/kotlin-compiler-embeddable-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.devtools.ksp/symbol-processing-api/1.9.22-1.0.16/ca56365e65965a5b9b4a6da4597221e22604ff34/symbol-processing-api-1.9.22-1.0.16.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.0/e000bd084353d84c9e888f6fb341dc1f5b79d948/kotlin-stdlib-jdk8-1.9.0.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.0/f320478990d05e0cfaadd74f9619fd6027adbf37/kotlin-stdlib-jdk7-1.9.0.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.22/d6c44cd08d8f3f9bece8101216dbe6553365c6e3/kotlin-stdlib-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.9.22/f8139a46fc677ec9badc49ae954392f4f5e7e7c7/kotlin-script-runtime-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.6.10/1cbe9c92c12a94eea200d23c2bbaedaf3daf5132/kotlin-reflect-1.6.10.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-daemon-embeddable/1.9.22/20e2c5df715f3240c765cfc222530e2796542021/kotlin-daemon-embeddable-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.intellij.deps/trove4j/1.0.20200330/3afb14d5f9ceb459d724e907a21145e8ff394f02/trove4j-1.0.20200330.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.compiler/compiler/1.5.8/b6b82a47735d855ae7050d1aa2f026dfeedaf635/compiler-1.5.8.jar\" />\n            </array>\n          </option>\n          <option name=\"pluginOptions\">\n            <array>\n              <option value=\"plugin:androidx.compose.plugins.idea:enabled=true\" />\n              <option value=\"plugin:androidx.compose.compiler.plugins.kotlin:sourceInformation=true\" />\n            </array>\n          </option>\n        </compilerArguments>\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"file://$MODULE_DIR$/../../../app/src/main/res;file://$MODULE_DIR$/../../../app/src/debug/res;file://$MODULE_DIR$/../../../app/build/generated/aboutLibraries/debug/res;file://$MODULE_DIR$/../../../app/build/generated/res/resValues/debug\" />\n        <option name=\"TEST_RES_FOLDERS_RELATIVE_PATH\" value=\"\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_17\">\n    <output url=\"file://$MODULE_DIR$/../../../app/build/intermediates/javac/debug/classes\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/aboutLibraries/debug/res\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/aboutLibraries/debug/res\" type=\"java-resource\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debug/out\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debug/out\" isTestSource=\"false\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debug/java\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debug/java\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debug/java\" isTestSource=\"false\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debug/kotlin\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debug/kotlin\" isTestSource=\"false\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/res/resValues/debug\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/res/resValues/debug\" type=\"java-resource\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/debug\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/source/buildConfig/debug\" isTestSource=\"false\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debug\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debug\" isTestSource=\"false\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kaptKotlin/debug\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kaptKotlin/debug\" isTestSource=\"false\" generated=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/src/debug\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/src/debug/res\" type=\"java-resource\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/src/main\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/src/main/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/src/main/res\" type=\"java-resource\" />\n    </content>\n    <orderEntry type=\"jdk\" jdkName=\"Android API 34, extension level 7 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.databinding:viewbinding:8.2.2@aar\" level=\"project\" />\n    <orderEntry type=\"module-library\">\n      <library name=\"Gradle: kaptGeneratedClasses\">\n        <CLASSES>\n          <root url=\"file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debug\" />\n        </CLASSES>\n        <JAVADOC />\n        <SOURCES />\n      </library>\n    </orderEntry>\n    <orderEntry type=\"library\" name=\"Gradle: androidx.fragment:fragment-testing:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.fragment:fragment-ktx:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.activity:activity-ktx:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.activity:activity:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.core:core:1.12.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.annotation:annotation-experimental:1.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-runtime:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.versionedparcelable:versionedparcelable:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.core:core-ktx:1.12.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.savedstate:savedstate:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-runtime-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.savedstate:savedstate-ktx:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.fragment:fragment:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.loader:loader:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.arch.core:core-runtime:2.2.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.viewpager:viewpager:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.customview:customview:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.fragment:fragment-testing-manifest:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.test:core:1.5.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.test:monitor:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.test:annotation:1.0.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.tracing:tracing:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.test.services:storage:1.4.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.appcompat:appcompat:1.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.appcompat:appcompat-resources:1.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.vectordrawable:vectordrawable:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.vectordrawable:vectordrawable-animated:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.interpolator:interpolator:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.cursoradapter:cursoradapter:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.drawerlayout:drawerlayout:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.android.material:material:1.11.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.cardview:cardview:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.coordinatorlayout:coordinatorlayout:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.constraintlayout:constraintlayout:2.1.4@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.dynamicanimation:dynamicanimation:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.legacy:legacy-support-core-utils:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.documentfile:documentfile:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.localbroadcastmanager:localbroadcastmanager:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.print:print:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.recyclerview:recyclerview:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.transition:transition:1.4.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.viewpager2:viewpager2:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.KotatsuApp:subsampling-scale-image-view:1b19231b2f@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:glide:4.15.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:gifdecoder:4.15.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.exifinterface:exifinterface:1.3.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-process:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.startup:startup-runtime:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.runtime:runtime-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.runtime:runtime-saveable-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-geometry-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-graphics-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-unit-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-text-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-util-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-service:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.palette:palette-ktx:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.palette:palette:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.solkin:disk-lru-cache:1.4@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-fragment-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-fragment:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-runtime:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-common:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.slidingpanelayout:slidingpanelayout:1.2.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-runtime-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-common-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-ui-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-ui:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.paging:paging-runtime-ktx:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.paging:paging-runtime:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.room:room-ktx:2.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.room:room-runtime:2.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.sqlite:sqlite:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.sqlite:sqlite-framework:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.mikepenz:aboutlibraries-core-android-debug:10.5.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.mikepenz:aboutlibraries:10.5.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.work:work-runtime-ktx:2.9.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.work:work-runtime:2.9.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.hilt:hilt-work:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.dagger:hilt-android:2.48.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.dagger:dagger-lint-aar:2.48.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.preference:preference-ktx:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.preference:preference:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.material3:material3-android:1.2.0-rc01@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.foundation:foundation-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.animation:animation-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.animation:animation-core-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.foundation:foundation-layout-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.material:material-icons-core-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.material:material-ripple-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.accompanist:accompanist-themeadapter-material3:0.33.1-alpha@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-tooling-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-tooling-data-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.ui:ui-tooling-preview-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.activity:activity-compose:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.accompanist:accompanist-pager-indicators:0.31.3-beta@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.accompanist:accompanist-pager:0.31.3-beta@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: dev.chrisbanes.snapper:snapper:0.2.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.material:material-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.navigation:navigation-compose:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.paging:paging-compose:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.compose.animation:animation-graphics-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.github.fornewid:material-motion-compose-navigation:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.github.fornewid:material-motion-compose-core:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.coil-kt:coil:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.coil-kt:coil-base:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.coil-kt:coil-compose:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: io.coil-kt:coil-compose-base:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.hilt:hilt-navigation-compose:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.hilt:hilt-navigation:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.annotation:annotation-jvm:1.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains:annotations:23.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.arch.core:core-common:2.2.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-common:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.collection:collection-jvm:1.4.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.collection:collection-ktx:1.4.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.code.findbugs:jsr305:3.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.guava:listenablefuture:1.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.concurrent:concurrent-futures:1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.resourceinspection:resourceinspection-annotation:1.0.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.code.gson:gson:2.10.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.okhttp3:okhttp:4.11.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.okio:okio-jvm:3.5.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.okhttp3:logging-interceptor:4.9.3\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:disklrucache:4.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.github.bumptech.glide:annotations:4.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.lifecycle:lifecycle-common-java8:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.paging:paging-common:3.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.paging:paging-common-ktx:3.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.room:room-common:2.6.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: androidx.hilt:hilt-common:1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.dagger:dagger:2.48.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: javax.inject:javax.inject:1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.google.dagger:hilt-core:2.48.1\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.retrofit2:retrofit:2.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.retrofit2:converter-moshi:2.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.moshi:moshi:1.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: com.squareup.moshi:moshi-kotlin:1.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" name=\"Gradle: org.jetbrains.kotlin:kotlin-reflect:1.8.22\" level=\"project\" />\n  </component>\n</module>"
  },
  {
    "path": ".idea/modules/app/CopyMangaJava.app.unitTest.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":app:unitTest\" external.linked.project.path=\"$MODULE_DIR$/../../../app\" external.root.project.path=\"$MODULE_DIR$/../../..\" external.system.id=\"GRADLE\" external.system.module.type=\"sourceSet\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"\" />\n        <option name=\"TEST_RES_FOLDERS_RELATIVE_PATH\" value=\"\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n      </configuration>\n    </facet>\n    <facet external-system-id=\"GRADLE\" type=\"kotlin-language\" name=\"Kotlin\">\n      <configuration version=\"4\" platform=\"JVM 17\" allPlatforms=\"JVM [17]\" useProjectSettings=\"false\">\n        <additionalVisibleModuleNames>:app:main</additionalVisibleModuleNames>\n        <compilerSettings />\n        <compilerArguments>\n          <option name=\"destination\" value=\"$MODULE_DIR$/../../../app/build/tmp/kotlin-classes/debugUnitTest\" />\n          <option name=\"noStdlib\" value=\"true\" />\n          <option name=\"noReflect\" value=\"true\" />\n          <option name=\"moduleName\" value=\"app_debugUnitTest\" />\n          <option name=\"jvmTarget\" value=\"17\" />\n          <option name=\"allowUnstableDependencies\" value=\"true\" />\n          <option name=\"allowNoSourceFiles\" value=\"true\" />\n          <option name=\"languageVersion\" value=\"1.9\" />\n          <option name=\"apiVersion\" value=\"1.9\" />\n          <option name=\"pluginClasspaths\">\n            <array>\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-parcelize-compiler/1.9.22/222c989e288e9a99c8579de44a0fe61230ddbfc5/kotlin-parcelize-compiler-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.devtools.ksp/symbol-processing/1.9.22-1.0.16/70b84dfb906092d3995f07ab28b24390f7547ae3/symbol-processing-1.9.22-1.0.16.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler-embeddable/1.9.22/9cd4dc7773cf2a99ecd961a88fbbc9a2da3fb5e1/kotlin-compiler-embeddable-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.devtools.ksp/symbol-processing-api/1.9.22-1.0.16/ca56365e65965a5b9b4a6da4597221e22604ff34/symbol-processing-api-1.9.22-1.0.16.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.9.0/e000bd084353d84c9e888f6fb341dc1f5b79d948/kotlin-stdlib-jdk8-1.9.0.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.9.0/f320478990d05e0cfaadd74f9619fd6027adbf37/kotlin-stdlib-jdk7-1.9.0.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.9.22/d6c44cd08d8f3f9bece8101216dbe6553365c6e3/kotlin-stdlib-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-script-runtime/1.9.22/f8139a46fc677ec9badc49ae954392f4f5e7e7c7/kotlin-script-runtime-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/1.6.10/1cbe9c92c12a94eea200d23c2bbaedaf3daf5132/kotlin-reflect-1.6.10.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-daemon-embeddable/1.9.22/20e2c5df715f3240c765cfc222530e2796542021/kotlin-daemon-embeddable-1.9.22.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains.intellij.deps/trove4j/1.0.20200330/3afb14d5f9ceb459d724e907a21145e8ff394f02/trove4j-1.0.20200330.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/13.0/919f0dfe192fb4e063e7dacadee7f8bb9a2672a9/annotations-13.0.jar\" />\n              <option value=\"$USER_HOME$/.gradle/caches/modules-2/files-2.1/androidx.compose.compiler/compiler/1.5.8/b6b82a47735d855ae7050d1aa2f026dfeedaf635/compiler-1.5.8.jar\" />\n            </array>\n          </option>\n          <option name=\"pluginOptions\">\n            <array>\n              <option value=\"plugin:androidx.compose.plugins.idea:enabled=true\" />\n            </array>\n          </option>\n        </compilerArguments>\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_17\">\n    <output-test url=\"file://$MODULE_DIR$/../../../app/build/intermediates/javac/debugUnitTest/classes\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ap_generated_sources/debugUnitTest/out\" />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debugUnitTest/java\" />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/ksp/debugUnitTest/kotlin\" />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kapt/debugUnitTest\" />\n    <content url=\"file://$MODULE_DIR$/../../../app/build/generated/source/kaptKotlin/debugUnitTest\" />\n    <content url=\"file://$MODULE_DIR$/../../../app/src/test\">\n      <sourceFolder url=\"file://$MODULE_DIR$/../../../app/src/test/java\" isTestSource=\"true\" />\n    </content>\n    <content url=\"file://$MODULE_DIR$/../../../app/src/testDebug\" />\n    <orderEntry type=\"jdk\" jdkName=\"Android API 34, extension level 7 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"module\" module-name=\"CopyMangaJava.app.main\" scope=\"TEST\" />\n    <orderEntry type=\"module-library\" scope=\"TEST\">\n      <library name=\"Gradle: kaptGeneratedClasses\">\n        <CLASSES>\n          <root url=\"file://$MODULE_DIR$/../../../app/build/tmp/kapt3/classes/debugUnitTest\" />\n        </CLASSES>\n        <JAVADOC />\n        <SOURCES />\n      </library>\n    </orderEntry>\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.databinding:viewbinding:8.2.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment-testing:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment-ktx:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.activity:activity-ktx:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.activity:activity:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.core:core:1.12.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.annotation:annotation-experimental:1.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-runtime:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.versionedparcelable:versionedparcelable:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.core:core-ktx:1.12.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.savedstate:savedstate:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-runtime-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.savedstate:savedstate-ktx:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.loader:loader:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.arch.core:core-runtime:2.2.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.viewpager:viewpager:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.customview:customview:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.fragment:fragment-testing-manifest:1.6.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test:core:1.5.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test:monitor:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test:annotation:1.0.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.tracing:tracing:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.test.services:storage:1.4.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.appcompat:appcompat:1.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.appcompat:appcompat-resources:1.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.vectordrawable:vectordrawable:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.vectordrawable:vectordrawable-animated:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.interpolator:interpolator:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.cursoradapter:cursoradapter:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.drawerlayout:drawerlayout:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.android.material:material:1.11.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.cardview:cardview:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.coordinatorlayout:coordinatorlayout:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.constraintlayout:constraintlayout:2.1.4@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.dynamicanimation:dynamicanimation:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.legacy:legacy-support-core-utils:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.documentfile:documentfile:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.localbroadcastmanager:localbroadcastmanager:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.print:print:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.recyclerview:recyclerview:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.transition:transition:1.4.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.viewpager2:viewpager2:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.KotatsuApp:subsampling-scale-image-view:1b19231b2f@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:glide:4.15.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:gifdecoder:4.15.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.exifinterface:exifinterface:1.3.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-process:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.startup:startup-runtime:1.1.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.runtime:runtime-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.runtime:runtime-saveable-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-geometry-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-graphics-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-unit-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-text-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-util-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-livedata-ktx:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-service:2.7.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.palette:palette-ktx:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.palette:palette:1.0.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.solkin:disk-lru-cache:1.4@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-fragment-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-fragment:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-runtime:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-common:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.slidingpanelayout:slidingpanelayout:1.2.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-runtime-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-common-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-ui-ktx:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-ui:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-runtime-ktx:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-runtime:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-ktx:2.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-runtime:2.6.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.sqlite:sqlite:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.sqlite:sqlite-framework:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.mikepenz:aboutlibraries-core-android-debug:10.5.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.mikepenz:aboutlibraries:10.5.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.work:work-runtime-ktx:2.9.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.work:work-runtime:2.9.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-work:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:hilt-android:2.48.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:dagger-lint-aar:2.48.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.preference:preference-ktx:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.preference:preference:1.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material3:material3-android:1.2.0-rc01@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.foundation:foundation-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.animation:animation-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.animation:animation-core-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.foundation:foundation-layout-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material:material-icons-core-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material:material-ripple-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.accompanist:accompanist-themeadapter-material3:0.33.1-alpha@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-tooling-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-tooling-data-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.ui:ui-tooling-preview-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.activity:activity-compose:1.8.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.accompanist:accompanist-pager-indicators:0.31.3-beta@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.accompanist:accompanist-pager:0.31.3-beta@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: dev.chrisbanes.snapper:snapper:0.2.2@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.material:material-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.navigation:navigation-compose:2.7.6@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-compose:3.2.1@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.compose.animation:animation-graphics-android:1.6.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.github.fornewid:material-motion-compose-navigation:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.github.fornewid:material-motion-compose-core:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil-base:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil-compose:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: io.coil-kt:coil-compose-base:2.4.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-navigation-compose:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-navigation:1.1.0@aar\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.annotation:annotation-jvm:1.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains:annotations:23.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.arch.core:core-common:2.2.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-common:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.collection:collection-jvm:1.4.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.collection:collection-ktx:1.4.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.code.findbugs:jsr305:3.0.2\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.guava:listenablefuture:1.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.concurrent:concurrent-futures:1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.22\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.resourceinspection:resourceinspection-annotation:1.0.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.code.gson:gson:2.10.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.okhttp3:okhttp:4.11.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.okio:okio-jvm:3.5.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.okhttp3:logging-interceptor:4.9.3\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:disklrucache:4.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.github.bumptech.glide:annotations:4.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.lifecycle:lifecycle-common-java8:2.7.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-common:3.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.paging:paging-common-ktx:3.2.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.room:room-common:2.6.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: androidx.hilt:hilt-common:1.1.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:dagger:2.48.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: javax.inject:javax.inject:1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.google.dagger:hilt-core:2.48.1\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.retrofit2:retrofit:2.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.retrofit2:converter-moshi:2.9.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.moshi:moshi:1.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: com.squareup.moshi:moshi-kotlin:1.15.0\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.jetbrains.kotlin:kotlin-reflect:1.8.22\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: junit:junit:4.13.2\" level=\"project\" />\n    <orderEntry type=\"library\" scope=\"TEST\" name=\"Gradle: org.hamcrest:hamcrest-core:1.3\" level=\"project\" />\n  </component>\n  <component name=\"TestModuleProperties\" production-module=\"CopyMangaJava.app.main\" />\n</module>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/modules/CopyMangaJava.iml\" filepath=\"$PROJECT_DIR$/.idea/modules/CopyMangaJava.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.iml\" filepath=\"$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.androidTest.iml\" filepath=\"$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.androidTest.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.main.iml\" filepath=\"$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.main.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.unitTest.iml\" filepath=\"$PROJECT_DIR$/.idea/modules/app/CopyMangaJava.app.unitTest.iml\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/navEditor.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"navEditor-manualLayoutAlgorithm2\">\n    <option name=\"myPositions\">\n      <map>\n        <entry key=\"aboutlibs_navigation.xml\">\n          <value>\n            <LayoutPositions>\n              <option name=\"myPositions\">\n                <map>\n                  <entry key=\"about_libraries_dest\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"12\" />\n                            <option name=\"y\" value=\"12\" />\n                          </Point>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                </map>\n              </option>\n            </LayoutPositions>\n          </value>\n        </entry>\n        <entry key=\"main_nav.xml\">\n          <value>\n            <LayoutPositions>\n              <option name=\"myPositions\">\n                <map>\n                  <entry key=\"aboutlibs_navigation\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"489\" />\n                            <option name=\"y\" value=\"3537\" />\n                          </Point>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"downloadFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"1110\" />\n                            <option name=\"y\" value=\"-1073\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_downloadFragment_to_downloadMangaInfoDialogFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"downloadInfoFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"755\" />\n                            <option name=\"y\" value=\"1857\" />\n                          </Point>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"downloadMangaInfoDialogFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"1143\" />\n                            <option name=\"y\" value=\"-668\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_downloadMangaInfoDialogFragment_to_mangaReaderActivity2\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"exploreFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"724\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_exploreFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"finishedFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"1080\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_finishedFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"historyFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"12\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_historyFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"hotFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"1436\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_hotFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"infoFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"475\" />\n                            <option name=\"y\" value=\"1436\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_infoFragment_to_mangaReaderActivity2\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"mainFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"-787\" />\n                            <option name=\"y\" value=\"1444\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_mainFragment_to_exploreFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_finishedFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_historyFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_hotFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_newestFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_personalFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_rankFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_recommendMangaFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_searchResultFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_mainFragment_to_settingFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"mangaReaderActivity2\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"714\" />\n                            <option name=\"y\" value=\"1436\" />\n                          </Point>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"newestFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"1792\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_newestFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"personalFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"283\" />\n                            <option name=\"y\" value=\"-711\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_personalFragment_to_downloadFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_personalFragment_to_downloadMangaInfoDialogFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_personalFragment_to_historyFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                            <entry key=\"action_personalFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"rankFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"2148\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_rankFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"recommendMangaFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"2504\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_recommendMangaFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"searchResultFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"253\" />\n                            <option name=\"y\" value=\"368\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_searchResultFragment_to_infoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"settingFragment\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"-28\" />\n                            <option name=\"y\" value=\"2965\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_settingFragment_to_downloadInfoFragment\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                </map>\n              </option>\n            </LayoutPositions>\n          </value>\n        </entry>\n        <entry key=\"setting_nav.xml\">\n          <value>\n            <LayoutPositions>\n              <option name=\"myPositions\">\n                <map>\n                  <entry key=\"aboutlibs_navigation\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"306\" />\n                            <option name=\"y\" value=\"-7\" />\n                          </Point>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"downloadInfoFragment2\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"349\" />\n                            <option name=\"y\" value=\"112\" />\n                          </Point>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                  <entry key=\"settingFragment2\">\n                    <value>\n                      <LayoutPositions>\n                        <option name=\"myPosition\">\n                          <Point>\n                            <option name=\"x\" value=\"40\" />\n                            <option name=\"y\" value=\"40\" />\n                          </Point>\n                        </option>\n                        <option name=\"myPositions\">\n                          <map>\n                            <entry key=\"action_settingFragment2_to_about_libraries\">\n                              <value>\n                                <LayoutPositions />\n                              </value>\n                            </entry>\n                          </map>\n                        </option>\n                      </LayoutPositions>\n                    </value>\n                  </entry>\n                </map>\n              </option>\n            </LayoutPositions>\n          </value>\n        </entry>\n      </map>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/other.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ScreenshotViewer\">\n    <option name=\"frameScreenshot\" value=\"true\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/render.experimental.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RenderSettings\">\n    <option name=\"quality\" value=\"0.0\" />\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=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2022 shizheng233\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# CopyMangaJava\n\n![GitHub all releases](https://img.shields.io/github/downloads/shizheng233/CopyMangaJava/total?label=%E4%B8%8B%E8%BD%BD&style=flat-square) ![Android Version Require](https://img.shields.io/badge/%E5%AE%89%E5%8D%93%E7%89%88%E6%9C%AC-%3E%3D%209.0-brightgreen?style=flat-square)\n\n*很抱歉，本软件已不再维护。*\n一个第三方的拷贝漫画带有M3(Material You)\n风格，支持动态主题。该App已通过Kotlin来实现，只是标题没改。注意：如果您感觉加载慢的话而且没有使用VPN的话，建议打开设置中的“使用境外CDN”,说不定可以加载得出来。\n\n希望大家可以多使用官方App，我写这个App只是用来练习。这个里面的代码都很简单，即使以后也可以给初学者一定的帮助。但我并不推荐您来查看我的代码。如果您想要学习的话，Kotatsu\n和 Tachiyomi的代码完全够用。多看几遍就可以弄懂。\n\n下载功能只能下载，在联网加载的时候会加载本地下载的漫画，但是我还没完成离线观看的逻辑。下载目录在\n_Android/com.shicheeng.copymanga/Downloads_ 下面，您可以自己手动复制到其他地方下观看。\n\n本项目部分迁移到Compose。\n\n**注意：请务必卸载以前的那个早期版本**\n\n## 灵感来源\n\n* [fumiama/copymanga](https://github.com/fumiama/copymanga)\n* [misaka10843/copymanga-downloader](https://github.com/misaka10843/copymanga-downloader)\n* [tachiyomi](https://github.com/tachiyomiorg/tachiyomi)\n* [kotatsu](https://github.com/KotatsuApp/Kotatsu)\n\n## 截屏\n\n<div>\n<img src=\"./sreenshots/001.png\" width=32% alt=\"1\"/>\n<img src=\"./sreenshots/002.png\" width=32%/>\n<img src=\"./sreenshots/003.png\" width=32%/>\n<img src=\"./sreenshots/004.png\" width=32%/>\n<img src=\"./sreenshots/005.png\" width=32%/>\n<img src=\"./sreenshots/006.png\" width=32%/>\n<img src=\"./sreenshots/007.png\" width=32%/>\n<img src=\"./sreenshots/008.png\" width=32%/>\n<img src=\"./sreenshots/009.png\" width=32%/>\n<img src=\"./sreenshots/010.png\" width=32%/>\n</div>\n\n## 关于Api\n\napi 来源于官方app API\n\n## 后续功能\n\n* ~~下载~~（现在可离线查看下载的漫画）\n* ~~记录位置~~（将历史记录保存在本地，_登录后可已上传到网页。_）\n* ~~登录~~(可以登录了，但是**多用户**没有测试过。)\n* ~~搜索~~(已完成)\n\n## License\n\nMIT License\n\n### 中文解释如下（来自[维基百科](https://zh.wikipedia.org/wiki/MIT%E8%A8%B1%E5%8F%AF%E8%AD%89)）\n\n#### 被许可人权利\n\n特此授予任何人免费获得本软件和相关文档文件（“软件”）副本的许可，不受限制地处理本软件，包括但不限于使用、复制、修改、合并\n、发布、分发、再许可的权利， 被许可人有权利使用、复制、修改、合并、出版发行、散布、再许可和/或贩售软件及软件的副本，及授予被供应人同等权利，惟服从以下义务。\n\n#### 被许可人义务\n\n在软件和软件的所有副本中都必须包含以上著作权声明和本许可声明。\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build"
  },
  {
    "path": "app/build.gradle",
    "content": "plugins {\n    id 'com.android.application'\n    id 'org.jetbrains.kotlin.android'\n    id 'kotlin-kapt'\n    id 'org.jetbrains.kotlin.plugin.parcelize'\n    id 'androidx.navigation.safeargs'\n    id 'com.mikepenz.aboutlibraries.plugin'\n    id 'kotlin-android'\n    id 'com.google.dagger.hilt.android'\n    id 'com.google.devtools.ksp'\n}\n\nandroid {\n\n\n    compileSdk 34\n\n    defaultConfig {\n        applicationId \"com.shicheeng.copymanga\"\n        minSdk 26\n        targetSdk 34\n        versionCode 3\n        versionName \"1.0.5-FIX-1\"\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n\n    buildTypes {\n        release {\n            minifyEnabled true\n            shrinkResources true\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    buildFeatures {\n        compose true\n        buildConfig true\n    }\n    kotlinOptions {\n        jvmTarget = '17'\n    }\n    androidResources {\n        generateLocaleConfig true\n    }\n    composeOptions {\n        kotlinCompilerExtensionVersion '1.5.8'\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_17\n        targetCompatibility JavaVersion.VERSION_17\n    }\n    viewBinding {\n        enabled = true\n    }\n    namespace 'com.shicheeng.copymanga'\n}\n\ndependencies {\n\n    implementation 'androidx.appcompat:appcompat:1.6.1'\n    implementation 'com.google.android.material:material:1.11.0'\n    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'\n    implementation 'com.google.code.gson:gson:2.10.1'\n    // define a BOM and its version\n    implementation(platform(\"com.squareup.okhttp3:okhttp-bom:4.9.3\"))\n\n    //SSIV\n    implementation 'com.github.KotatsuApp:subsampling-scale-image-view:1b19231b2f'\n\n    //Okhttp\n    // define any required OkHttp artifacts without version\n    implementation(\"com.squareup.okhttp3:okhttp\")\n    implementation(\"com.squareup.okhttp3:logging-interceptor\")\n    implementation 'com.squareup.okio:okio:3.5.0'\n\n    //Glide\n    implementation 'com.github.bumptech.glide:glide:4.15.0'\n\n    //Core\n    implementation 'androidx.core:core-ktx:1.12.0'\n    implementation 'androidx.lifecycle:lifecycle-process:2.7.0'\n\n    ksp 'com.github.bumptech.glide:compiler:4.13.2'\n\n\n    def lifecycle_version = \"2.6.1\"\n    // ViewModel\n    implementation \"androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version\"\n    // ViewModel utilities for Compose\n    implementation \"androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version\"\n    // LiveData\n    implementation \"androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version\"\n    //Service\n    implementation \"androidx.lifecycle:lifecycle-service:$lifecycle_version\"\n    implementation \"androidx.fragment:fragment-ktx:1.6.2\"\n    implementation \"androidx.activity:activity-ktx:1.8.2\"\n    implementation 'androidx.palette:palette-ktx:1.0.0'\n\n    //Cache\n    implementation 'com.github.solkin:disk-lru-cache:1.4'\n\n\n    //Navigation\n    def nav_version = \"2.7.6\"\n    // Kotlin\n    implementation \"androidx.navigation:navigation-fragment-ktx:$nav_version\"\n    implementation \"androidx.navigation:navigation-ui-ktx:$nav_version\"\n\n    //Paging3\n    def paging_version = \"3.1.1\"\n    implementation \"androidx.paging:paging-runtime-ktx:$paging_version\"\n\n    // Testing Fragments in Isolation\n    debugImplementation \"androidx.fragment:fragment-testing:1.6.2\"\n\n    //Room\n    implementation \"androidx.room:room-ktx:2.6.1\"\n    ksp \"androidx.room:room-compiler:2.6.1\"\n    androidTestImplementation \"androidx.room:room-testing:2.6.1\"\n\n    //AboutLibrary\n    def latestAboutLibsRelease = \"10.5.2\"\n    implementation \"com.mikepenz:aboutlibraries-core:$latestAboutLibsRelease\"\n    implementation \"com.mikepenz:aboutlibraries:${latestAboutLibsRelease}\"\n\n    implementation \"androidx.work:work-runtime-ktx:2.9.0\"\n    implementation 'androidx.hilt:hilt-work:1.1.0'\n    // When using Kotlin.\n    kapt 'androidx.hilt:hilt-compiler:1.1.0'\n\n    //Android Preference\n    implementation 'androidx.preference:preference-ktx:1.2.1'\n\n    //Compose\n    // Import the Compose BOM\n    implementation platform('androidx.compose:compose-bom:2024.01.00')\n    // Override Material Design 3 library version with a pre-release version\n    implementation 'androidx.compose.material3:material3:1.2.0-rc01'\n    // Import other Compose libraries without version numbers\n    implementation 'androidx.compose.foundation:foundation'\n    implementation \"com.google.accompanist:accompanist-themeadapter-material3:0.33.1-alpha\"\n    implementation 'androidx.compose.ui:ui-tooling'\n    implementation 'androidx.activity:activity-compose:1.8.2'\n    implementation \"com.google.accompanist:accompanist-pager-indicators:0.31.3-beta\"\n    implementation \"androidx.navigation:navigation-compose:2.7.6\"\n    //Optional - Jetpack Compose integration\n    implementation \"androidx.paging:paging-compose:3.2.1\"\n    //Anime\n    implementation \"androidx.compose.animation:animation-graphics\"\n    implementation \"io.github.fornewid:material-motion-compose-navigation:1.1.0\"\n\n    //Coil\n    implementation \"io.coil-kt:coil:2.4.0\"\n    implementation \"io.coil-kt:coil-compose:2.4.0\"\n\n    //Retrofit\n    implementation \"com.squareup.retrofit2:retrofit:2.9.0\"\n    implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'\n\n    //Moshi\n    implementation \"com.squareup.moshi:moshi-kotlin:1.15.0\"\n    ksp \"com.squareup.moshi:moshi-kotlin-codegen:1.14.0\"\n\n    //Hilt\n    implementation \"com.google.dagger:hilt-android:2.48.1\"\n    kapt \"com.google.dagger:hilt-compiler:2.48.1\"\n    implementation 'androidx.hilt:hilt-navigation-compose:1.1.0'\n\n    testImplementation 'junit:junit:4.13.2'\n    androidTestImplementation 'androidx.test.ext:junit:1.1.5'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'\n}\n\nkapt {\n    correctErrorTypes true\n}"
  },
  {
    "path": "app/debug/output-metadata.json",
    "content": "{\n  \"version\": 3,\n  \"artifactType\": {\n    \"type\": \"APK\",\n    \"kind\": \"Directory\"\n  },\n  \"applicationId\": \"com.shicheeng.copymanga\",\n  \"variantName\": \"debug\",\n  \"elements\": [\n    {\n      \"type\": \"SINGLE\",\n      \"filters\": [],\n      \"attributes\": [],\n      \"versionCode\": 1,\n      \"versionName\": \"1.0.2\",\n      \"outputFile\": \"app-debug.apk\"\n    }\n  ],\n  \"elementType\": \"File\"\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.shicheeng.copymanga.data.MangaInfoChapterDataBean\n-keep class com.shicheeng.copymanga.data.LastMangaDownload\n-keep class com.shicheeng.copymanga.data.MangaDownloadChapterInfoModel\n-keep class com.shicheeng.copymanga.data.MangaDownloads\n-keep class com.shicheeng.copymanga.data.PersonalInnerDataModel\n-keep class com.shicheeng.copymanga.data.MangaSortBean\n\n# Please add these rules to your existing keep rules in order to suppress warnings.\n# This is generated automatically by the Android Gradle plugin.\n-dontwarn org.bouncycastle.jsse.BCSSLParameters\n-dontwarn org.bouncycastle.jsse.BCSSLSocket\n-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider\n-dontwarn org.conscrypt.Conscrypt$Version\n-dontwarn org.conscrypt.Conscrypt\n-dontwarn org.conscrypt.ConscryptHostnameVerifier\n-dontwarn org.openjsse.javax.net.ssl.SSLParameters\n-dontwarn org.openjsse.javax.net.ssl.SSLSocket\n-dontwarn org.openjsse.net.ssl.OpenJSSE\n\n# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and\n# EnclosingMethod is required to use InnerClasses.\n-keepattributes Signature, InnerClasses, EnclosingMethod\n\n# Retrofit does reflection on method and parameter annotations.\n-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations\n\n# Keep annotation default values (e.g., retrofit2.http.Field.encoded).\n-keepattributes AnnotationDefault\n\n# Retain service method parameters when optimizing.\n-keepclassmembers,allowshrinking,allowobfuscation interface * {\n    @retrofit2.http.* <methods>;\n}\n\n# Ignore annotation used for build tooling.\n-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement\n\n# Ignore JSR 305 annotations for embedding nullability information.\n-dontwarn javax.annotation.**\n\n# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.\n-dontwarn kotlin.Unit\n\n# Top-level functions that can only be used by Kotlin.\n-dontwarn retrofit2.KotlinExtensions\n-dontwarn retrofit2.KotlinExtensions$*\n\n# With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy\n# and replaces all potential values with null. Explicitly keeping the interfaces prevents this.\n-if interface * { @retrofit2.http.* <methods>; }\n-keep,allowobfuscation interface <1>\n\n# Keep inherited services.\n-if interface * { @retrofit2.http.* <methods>; }\n-keep,allowobfuscation interface * extends <1>\n\n# With R8 full mode generic signatures are stripped for classes that are not\n# kept. Suspend functions are wrapped in continuations where the type argument\n# is used.\n-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation\n\n# R8 full mode strips generic signatures from return types if not kept.\n-if interface * { @retrofit2.http.* public *** *(...); }\n-keep,allowoptimization,allowshrinking,allowobfuscation class <3>"
  },
  {
    "path": "app/release/output-metadata.json",
    "content": "{\n  \"version\": 3,\n  \"artifactType\": {\n    \"type\": \"APK\",\n    \"kind\": \"Directory\"\n  },\n  \"applicationId\": \"com.shicheeng.copymanga\",\n  \"variantName\": \"release\",\n  \"elements\": [\n    {\n      \"type\": \"SINGLE\",\n      \"filters\": [],\n      \"attributes\": [],\n      \"versionCode\": 3,\n      \"versionName\": \"1.0.5-FIX-1\",\n      \"outputFile\": \"app-release.apk\"\n    }\n  ],\n  \"elementType\": \"File\"\n}"
  },
  {
    "path": "app/src/androidTest/java/com/shicheeng/copymanga/ExampleInstrumentedTest.java",
    "content": "package com.shicheeng.copymanga;\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        assertEquals(\"com.shicheeng.copymanga\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "app/src/debug/res/drawable-anydpi/ic_explore_outline.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM6.5,17.5l7.51,-3.49L17.5,6.5 9.99,9.99 6.5,17.5zM12,10.9c0.61,0 1.1,0.49 1.1,1.1s-0.49,1.1 -1.1,1.1 -1.1,-0.49 -1.1,-1.1 0.49,-1.1 1.1,-1.1z\" />\n</vector>\n"
  },
  {
    "path": "app/src/debug/res/drawable-anydpi/ic_setting_outline.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98 0,0.33 0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z\" />\n</vector>\n"
  },
  {
    "path": "app/src/debug/res/drawable-anydpi/ic_swith_horiz.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\"\n    android:tint=\"?colorControlNormal\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/debug/res/drawable-anydpi/ic_swith_vert.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M16,17.01V10h-2v7.01h-3L15,21l4,-3.99h-3zM9,3L5,6.99h3V14h2V6.99h3L9,3z\" />\n\n</vector>\n"
  },
  {
    "path": "app/src/debug/res/drawable-anydpi/ic_trend_up.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\"\n    android:tint=\"#333333\"\n    android:alpha=\"0.6\"\n    android:autoMirrored=\"true\">\n  <group android:scaleX=\"1.0909091\"\n      android:scaleY=\"1.0909091\"\n      android:translateX=\"-1.0909091\"\n      android:translateY=\"-1.0909091\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/debug/res/mipmap-anydpi-v26/ic_copy.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=\"@color/ic_copy_background\"/>\n    <foreground android:drawable=\"@mipmap/ic_copy_foreground\"/>\n</adaptive-icon>"
  },
  {
    "path": "app/src/debug/res/values/ic_copy_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"ic_copy_background\">#2A85C6</color>\n</resources>"
  },
  {
    "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    xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.POST_NOTIFICATIONS\" />\n\n    <application\n        android:name=\".MyApp\"\n        android:allowBackup=\"true\"\n        android:enableOnBackInvokedCallback=\"true\"\n        android:icon=\"@mipmap/ic_copy\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_copy\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.CopyMangaNew\"\n        android:windowSoftInputMode=\"adjustNothing\"\n        tools:targetApi=\"tiramisu\">\n        <activity\n            android:name=\".MainActivity\"\n            android:exported=\"true\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n\n                <data\n                    android:host=\"download\"\n                    android:scheme=\"shicheengcmdm\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n                <category android:name=\"android.intent.category.DEFAULT\" />\n\n                <data\n                    android:host=\"detail\"\n                    android:scheme=\"shicheengcmdm\" />\n            </intent-filter>\n            <intent-filter>\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n                <category android:name=\"android.intent.category.BROWSABLE\" />\n\n                <data android:scheme=\"https\" />\n                <data android:pathPrefix=\"/h5/details/comic\" />\n                <data android:host=\"copymanga.site\" />\n                <data android:host=\"copymanga.org\" />\n                <data android:host=\"copymanga.info\" />\n                <data android:host=\"copymanga.net\" />\n            </intent-filter>\n\n        </activity>\n        <activity android:name=\".MangaReaderActivity\" />\n        <activity\n            android:name=\".error.ErrorActivity\"\n            android:process=\":exception_process\" />\n\n        <provider\n            android:name=\"androidx.startup.InitializationProvider\"\n            android:authorities=\"${applicationId}.androidx-startup\"\n            android:exported=\"false\"\n            tools:node=\"merge\">\n            <!-- If you are using androidx.startup to initialize other components -->\n            <meta-data\n                android:name=\"androidx.work.WorkManagerInitializer\"\n                android:value=\"androidx.startup\"\n                tools:node=\"remove\" />\n        </provider>\n\n        <service\n            android:name=\"androidx.work.impl.foreground.SystemForegroundService\"\n            android:foregroundServiceType=\"dataSync\"\n            tools:node=\"merge\" />\n\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/CrashHandler.kt",
    "content": "package com.shicheeng.copymanga\n\nimport android.content.Context\nimport com.shicheeng.copymanga.error.ErrorActivity\nimport java.lang.Thread.UncaughtExceptionHandler\n\n@Deprecated(\"先暂时弃用，这个方法还没学会\")\nclass CrashHandler(\n    private val context: Context,\n) : UncaughtExceptionHandler {\n\n    init {\n        Thread.setDefaultUncaughtExceptionHandler(this)\n    }\n\n    override fun uncaughtException(\n        thread: Thread,\n        error: Throwable,\n    ) {\n        ErrorActivity.newIntentInstance(context = context, error.message).let {\n            context.startActivity(it)\n        }\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/MainActivity.kt",
    "content": "package com.shicheeng.copymanga\n\nimport android.Manifest\nimport android.content.DialogInterface\nimport android.content.Intent\nimport android.content.pm.PackageManager\nimport android.net.Uri\nimport android.os.Build\nimport android.os.Bundle\nimport android.text.Html\nimport androidx.activity.compose.setContent\nimport androidx.activity.viewModels\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.staticCompositionLocalOf\nimport androidx.core.app.ActivityCompat\nimport androidx.core.content.ContextCompat\nimport androidx.core.text.buildSpannedString\nimport androidx.core.view.WindowCompat\nimport com.google.android.material.dialog.MaterialAlertDialogBuilder\nimport com.shicheeng.copymanga.app.AppAttachCompatActivity\nimport com.shicheeng.copymanga.data.VersionUnit\nimport com.shicheeng.copymanga.ui.screen.MainComposeNavigation\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.ui.theme.CopyMangaTheme\nimport com.shicheeng.copymanga.util.FileCacheUtils\nimport com.shicheeng.copymanga.util.collectRepeatLifecycle\nimport com.shicheeng.copymanga.viewmodel.RootViewModel\nimport dagger.hilt.android.AndroidEntryPoint\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nclass MainActivity : AppAttachCompatActivity() {\n\n    @Inject\n    lateinit var settingPref: SettingPref\n\n    private val mainViewModel by viewModels<RootViewModel>()\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        WindowCompat.setDecorFitsSystemWindows(window, false)\n        requestNotificationsPermission()\n        setContent {\n            CopyMangaTheme {\n                CompositionLocalProvider(\n                    LocalSettingPreference provides settingPref,\n                ) {\n                    MainComposeNavigation()\n                }\n            }\n        }\n\n        if (!settingPref.pauseUpdateDetector.value) {\n            mainViewModel.updateData.collectRepeatLifecycle(this) {\n                onUpdateAttach(it)\n            }\n        }\n\n    }\n\n    private fun requestNotificationsPermission() {\n        if (\n            Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&\n            ContextCompat.checkSelfPermission(\n                /*context=*/this,\n                Manifest.permission.POST_NOTIFICATIONS\n            ) != PackageManager.PERMISSION_GRANTED\n        ) {\n            ActivityCompat.requestPermissions(\n                this,\n                arrayOf(Manifest.permission.POST_NOTIFICATIONS),\n                1\n            )\n        }\n    }\n\n    /**\n     * 更新弹窗。由于一般的更新内容为简体中文，故不做i18n处理。\n     * @param versionUnit 版本更新单位，为空则表示没有更新。\n     *\n     * @author ShihCheeng and refer to Kotatsu.\n     */\n    private fun onUpdateAttach(versionUnit: VersionUnit?) {\n        if (versionUnit == null) {\n            return\n        }\n        val message = buildSpannedString {\n            append(\"<b>版本：</b>\")\n            append(versionUnit.versionName)\n            appendLine(\"<b>大小：</b>\" + FileCacheUtils.getFormatSize(versionUnit.apkSize.toDouble()))\n            appendLine(\"<b>类型：</b>\" + versionUnit.versionId.type)\n            appendLine()\n            appendLine(versionUnit.description)\n        }\n        val dialog = MaterialAlertDialogBuilder(\n            this,\n            com.google.android.material.R.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered\n        ).apply {\n            setTitle(R.string.new_version)\n            setMessage(Html.fromHtml(message.toString(), Html.FROM_HTML_MODE_COMPACT))\n            setIcon(R.drawable.baseline_security_update_24)\n        }\n        dialog.setPositiveButton(R.string.update) { dialogInterface: DialogInterface, _: Int ->\n            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(versionUnit.apkUrl))\n            startActivity(intent)\n            dialogInterface.dismiss()\n        }\n        dialog.setNegativeButton(android.R.string.cancel) { dialogInterface: DialogInterface, _: Int ->\n            dialogInterface.dismiss()\n        }\n        dialog.setNeutralButton(R.string.website_look) { dialogInterface: DialogInterface, _: Int ->\n            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(versionUnit.htmlUrl))\n            startActivity(intent)\n            dialogInterface.dismiss()\n        }\n        dialog.show()\n    }\n\n\n}\n\nval LocalSettingPreference = staticCompositionLocalOf<SettingPref> {\n    error(\"NO LOCAL SETTING PROVIDE\")\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/MangaReaderActivity.kt",
    "content": "package com.shicheeng.copymanga\n\nimport android.annotation.TargetApi\nimport android.content.Context\nimport android.content.Intent\nimport android.content.res.ColorStateList\nimport android.graphics.drawable.RippleDrawable\nimport android.os.Build\nimport android.os.Bundle\nimport android.transition.Slide\nimport android.transition.TransitionManager\nimport android.transition.TransitionSet\nimport android.view.Gravity\nimport android.view.KeyEvent\nimport android.view.MotionEvent\nimport android.view.ViewGroup\nimport android.view.WindowManager\nimport androidx.activity.viewModels\nimport androidx.core.graphics.ColorUtils\nimport androidx.core.graphics.Insets\nimport androidx.core.view.WindowCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.core.view.WindowInsetsControllerCompat\nimport androidx.core.view.isGone\nimport androidx.core.view.isInvisible\nimport androidx.core.view.isVisible\nimport androidx.core.view.updateLayoutParams\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.lifecycleScope\nimport androidx.viewpager2.widget.ViewPager2.LAYOUT_DIRECTION_LTR\nimport androidx.viewpager2.widget.ViewPager2.LAYOUT_DIRECTION_RTL\nimport com.google.android.material.shape.MaterialShapeDrawable\nimport com.shicheeng.copymanga.app.AppAttachCompatActivity\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.ReaderContent\nimport com.shicheeng.copymanga.data.ReaderState\nimport com.shicheeng.copymanga.databinding.ActivityMangaReaderBinding\nimport com.shicheeng.copymanga.dialog.ConfigPagerSheet\nimport com.shicheeng.copymanga.fm.delegate.IdlingDelegate\nimport com.shicheeng.copymanga.fm.reader.MangaLoader\nimport com.shicheeng.copymanga.fm.reader.ReaderManager\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\nimport com.shicheeng.copymanga.fm.reader.noraml.PageSliderFormatter\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.GestureHelper\nimport com.shicheeng.copymanga.util.PageSelectPosition\nimport com.shicheeng.copymanga.util.ReaderSliderAttach\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.util.getThemeColor\nimport com.shicheeng.copymanga.util.hasGlobalPoint\nimport com.shicheeng.copymanga.util.observe\nimport com.shicheeng.copymanga.util.transformPair\nimport com.shicheeng.copymanga.view.control.ReaderControl\nimport com.shicheeng.copymanga.viewmodel.ReaderViewModel\nimport dagger.hilt.android.AndroidEntryPoint\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.util.concurrent.TimeUnit\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nclass MangaReaderActivity : AppAttachCompatActivity(),\n    ConfigPagerSheet.CallBack,\n    PageSelectPosition,\n    GestureHelper.GestureListener,\n    ReaderControl.ControlDelegateListener,\n    IdlingDelegate.IdleCallback {\n\n\n    private lateinit var binding: ActivityMangaReaderBinding\n\n    private val viewModel by viewModels<ReaderViewModel>()\n    private val windowInsetsController by lazy {\n        WindowInsetsControllerCompat(window, binding.root)\n    }\n\n\n    @Inject\n    lateinit var settingPref: SettingPref\n\n\n    private lateinit var readerManager: ReaderManager\n    private lateinit var gestureHelper: GestureHelper\n    private lateinit var control: ReaderControl\n    private var isLast: Boolean = false\n    private var gestureInsets: Insets = Insets.NONE\n    private val idlingDelegate = IdlingDelegate(this)\n\n    override val readerMode: ReaderMode?\n        get() = readerManager.currentReaderMode\n\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        binding = ActivityMangaReaderBinding.inflate(layoutInflater)\n        setContentView(binding.root)\n        WindowCompat.setDecorFitsSystemWindows(window, false)\n        setCutoutShort(settingPref.cutoutDisplay)\n        windowsInsets(binding.root) { view, systemGesture ->\n            gestureInsets = systemGesture\n            binding.mangaReaderToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {\n                topMargin = top\n            }\n            binding.mangaReaderBottomToolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {\n                bottomMargin = bottom\n            }\n            view.updateLayoutParams<ViewGroup.MarginLayoutParams> {\n                leftMargin = left\n                rightMargin = right\n            }\n        }\n\n        readerManager = ReaderManager(supportFragmentManager, R.id.manga_reader_container)\n        gestureHelper = GestureHelper(this, this)\n        control = ReaderControl(this, settingPref = settingPref)\n\n        viewModel.readerModel.observe(this, Lifecycle.State.STARTED) {\n            initializeReaderMode(it)\n        }\n        viewModel.information.transformPair().observe(this, this::onUIChange)\n        viewModel.errorHandler.observe(this, this::onError)\n        viewModel.loadingCounter.observe(this, this::onLoading)\n        viewModel.mangaContent.observe(this, this::withPageContent)\n\n        initializeBottomMenu()\n        binding.mangaReaderSlider.setLabelFormatter(PageSliderFormatter())\n        ReaderSliderAttach(this, viewModel).attach(binding.mangaReaderSlider)\n        binding.mangaReaderNext.setOnClickListener { loadChapter(true) }\n        binding.mangaReaderPrevious.setOnClickListener { loadChapter(false) }\n        idlingDelegate.bindToLifecycle(this)\n    }\n\n\n    private fun initializeReaderMode(readerMode: ReaderMode?) {\n        if (readerMode == null) return\n        binding.readerMangaModeTip.text = when (readerMode) {\n            ReaderMode.NORMAL -> getString(R.string.japanese_r_to_l)\n            ReaderMode.STANDARD -> getString(R.string.manga_mode_l_t_r)\n            ReaderMode.WEBTOON -> getString(R.string.korea_chinese_top_to_bottom)\n        }\n        if (readerManager.currentReaderMode != readerMode) {\n            readerManager.replace(readerMode)\n        }\n    }\n\n    private fun withPageContent(readerContent: ReaderContent) {\n        if (readerContent.list.isNotEmpty()) {\n            hideSystemBar(true)\n        }\n    }\n\n\n    private fun initializeBottomMenu() {\n        setSupportActionBar(binding.mangaReaderToolbar)\n        supportActionBar?.setDisplayHomeAsUpEnabled(true)\n        binding.mangaReaderToolbar.setNavigationOnClickListener { finish() }\n        //The bottom menu refer from Tachiyomi\n        val materialShape = (binding.mangaReaderToolbar.background as MaterialShapeDrawable)\n            .apply {\n                elevation =\n                    resources.getDimension(com.google.android.material.R.dimen.m3_sys_elevation_level2)\n                alpha = 242\n            }\n        binding.mangaReaderBottomToolbar.background = materialShape.copy(this@MangaReaderActivity)\n        binding.mangaReaderSeeker.background = materialShape.copy(this@MangaReaderActivity)?.apply {\n            setCornerSize(999f)\n        }\n\n        listOf(\n            binding.mangaReaderPrevious,\n            binding.mangaReaderNext,\n            binding.mangaReaderSetting\n        ).forEach {\n            it.background = binding.mangaReaderSeeker.background.copy(this)\n            it.foreground = RippleDrawable(\n                ColorStateList.valueOf(getThemeColor(android.R.attr.colorControlHighlight)),\n                null,\n                it.background,\n            )\n        }\n\n        binding.mangaReaderSetting.setOnClickListener {\n            ConfigPagerSheet.show(\n                fragmentManager = supportFragmentManager,\n                reader = readerManager.currentReaderMode ?: return@setOnClickListener\n            )\n        }\n\n        val toolbarColor = ColorUtils.setAlphaComponent(\n            materialShape.resolvedTintColor,\n            materialShape.alpha\n        )\n        window.statusBarColor = toolbarColor\n        window.navigationBarColor = toolbarColor\n    }\n\n    // FIXME: 有时候没有提示\n    private fun onUIChange(pair: Pair<ReaderState?, ReaderState?>) {\n        val (old: ReaderState?, state: ReaderState?) = pair\n        title = state?.mangaName ?: old?.mangaName ?: getString(android.R.string.unknownName)\n        if (state == null) {\n            supportActionBar?.subtitle = null\n            binding.mangaReaderSeeker.isVisible = false\n            return\n        }\n        binding.readerMangaSubtitle.text = state.subTime ?: getString(R.string.local)\n        supportActionBar?.subtitle =\n            state.chapterName ?: getString(android.R.string.unknownName)\n\n        isLast = state.currentPage == state.totalPage - 1\n\n        if (old?.chapterName != null && state.chapterName != old.chapterName) {\n            if (!state.chapterName.isNullOrEmpty()) {\n                binding.mangaReaderCircularProgressIndicator.tip(\n                    state.chapterName,\n                    TimeUnit.SECONDS.toMillis(1)\n                )\n            }\n        }\n\n        binding.mangaReaderPageIndicator.text =\n            getString(R.string.chapter_page_indicator, (state.currentPage + 1), state.totalPage)\n        binding.mangaReaderChapterTotalNumber.text = state.totalPage.toString()\n        binding.mangaReaderChapterNowNumber.text = (state.currentPage.plus(1)).toString()\n\n        if (!state.isSliderAvailable()) {\n            binding.mangaReaderSeeker.isInvisible = true\n        } else {\n            binding.mangaReaderSeeker.isInvisible = false\n            binding.mangaReaderSlider.valueTo = (state.totalPage.toFloat() - 1)\n            binding.mangaReaderSlider.value = state.currentPage.toFloat()\n        }\n        viewModel.saveLocalChapterState(state.currentPage)\n    }\n\n    override fun onPositionCallBack(page: MangaReaderPage) {\n        lifecycleScope.launch(Dispatchers.Default) {\n            val pages = viewModel.mangaContent.value.list\n            val index = pages.indexOfFirst { it.urlHashCode == page.urlHashCode }\n            if (index != -1) {\n                withContext(Dispatchers.Main) {\n                    readerManager.currentReader?.moveToPosition(position = index, index <= 2)\n                }\n            }\n        }\n    }\n\n    override fun onTouch(area: Int) {\n        control.onGridTouch(area, binding.mangaReaderContainer)\n    }\n\n    override fun onProcessTouch(rawX: Int, rawY: Int): Boolean {\n        return if (\n            rawX <= gestureInsets.left ||\n            rawY <= gestureInsets.top ||\n            rawX >= binding.root.width - gestureInsets.right ||\n            rawY >= binding.root.height - gestureInsets.bottom ||\n            binding.mangaReaderToolbar.hasGlobalPoint(rawX, rawY) ||\n            binding.mangaReaderBottomToolbar.hasGlobalPoint(rawX, rawY)\n        ) {\n            false\n        } else {\n            val touchable = window.peekDecorView()?.touchables\n            touchable?.none { it.hasGlobalPoint(rawX, rawY) } ?: true\n        }\n    }\n\n    override fun scrollPage(delta: Int) {\n        readerManager.currentReader?.moveDelta(delta)\n    }\n\n    override fun hide() {\n        hideSystemBar(binding.mangaReaderToolbar.isVisible)\n    }\n\n    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {\n        gestureHelper.dispatchTouchEvent(ev)\n        return super.dispatchTouchEvent(ev)\n    }\n\n    private fun loadChapter(isNext: Boolean) {\n        val uuid = viewModel.getCurrentReaderState().uuid\n        viewModel.loadNextPrvChapter(uuid, isNext)\n    }\n\n    override fun onIdle() {\n        viewModel.saveCurrentState(readerManager.currentReader?.currentState())\n    }\n\n    override fun onUserInteraction() {\n        super.onUserInteraction()\n        idlingDelegate.onUserInteraction()\n    }\n\n    override fun onModeChange(mode: ReaderMode) {\n        rebuildReaderNavigation(mode)\n        viewModel.switchMode(mode)\n        viewModel.saveCurrentState(readerManager.currentReader?.currentState())\n    }\n\n    private fun onError(e: Throwable?) {\n        with(binding.layoutErrorInclude) {\n            errorTextTip.setTextColor(getThemeColor(com.google.android.material.R.attr.colorSurface))\n            errorTextTipDesc.apply {\n                setTextColor(getThemeColor(com.google.android.material.R.attr.colorSurface))\n                text = e?.message\n            }\n            btnErrorRetry.setOnClickListener {\n                viewModel.retry()\n                this.root.isVisible = false\n            }\n        }\n    }\n\n    private fun onLoading(boolean: Boolean) {\n        val hasPages = viewModel.mangaContent.value.list.isNotEmpty()\n        binding.loadIndicator.isVisible = boolean && !hasPages\n        if (boolean && hasPages) {\n            binding.mangaReaderCircularProgressIndicator.show(R.string.in_loading_next_chapter)\n        } else {\n            binding.mangaReaderCircularProgressIndicator.hide()\n        }\n    }\n\n    private fun rebuildReaderNavigation(mode: ReaderMode) {\n        if (mode == ReaderMode.STANDARD || mode == ReaderMode.WEBTOON) {\n            binding.mangaReaderNav.layoutDirection = LAYOUT_DIRECTION_LTR\n        } else {\n            binding.mangaReaderNav.layoutDirection = LAYOUT_DIRECTION_RTL\n        }\n    }\n\n    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {\n        return when (keyCode) {\n            KeyEvent.KEYCODE_VOLUME_UP -> {\n                readerManager.currentReader?.moveDelta(-1)\n                true\n            }\n\n            KeyEvent.KEYCODE_VOLUME_DOWN -> {\n                readerManager.currentReader?.moveDelta(1)\n                true\n            }\n\n            else -> super.onKeyDown(keyCode, event)\n        }\n    }\n\n\n    private fun hideSystemBar(\n        isHide: Boolean,\n    ) {\n        val transition = TransitionSet()\n            .setOrdering(TransitionSet.ORDERING_TOGETHER)\n            .addTransition(Slide(Gravity.TOP).addTarget(binding.mangaReaderToolbar))\n            .addTransition(Slide(Gravity.BOTTOM).addTarget(binding.mangaReaderBottomSheet))\n        TransitionManager.beginDelayedTransition(binding.root, transition)\n        binding.mangaReaderBottomSheet.isGone = isHide\n        binding.mangaReaderToolbar.isGone = isHide\n        binding.mangaReaderPageIndicator.isVisible = isHide\n        if (isHide) {\n            windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())\n            windowInsetsController.systemBarsBehavior =\n                WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE\n        } else {\n            windowInsetsController.show(WindowInsetsCompat.Type.systemBars())\n            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)\n        }\n\n    }\n\n    @TargetApi(Build.VERSION_CODES.P)\n    private fun setCutoutShort(enabled: Boolean) {\n        window.attributes.layoutInDisplayCutoutMode = when (enabled) {\n            true -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES\n            false -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER\n        }\n\n        // Trigger relayout\n        hideSystemBar(!binding.mangaReaderToolbar.isVisible)\n    }\n\n    companion object {\n\n        /**\n         * 跳转到[MangaReaderActivity]\n         * @param pathWord Path word\n         * @param uuid 章节uuid\n         */\n        fun newInstance(\n            context: Context,\n            pathWord: String,\n            uuid: String,\n        ): Intent {\n            val intent = Intent(context, MangaReaderActivity::class.java)\n            intent.putExtra(MangaLoader.MANGA_PATH_WORD, pathWord)\n            intent.putExtra(MangaLoader.MANGA_UUID, uuid)\n            return intent\n        }\n\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/MyApp.kt",
    "content": "package com.shicheeng.copymanga\n\nimport android.app.Application\nimport android.app.NotificationChannel\nimport android.app.NotificationManager\nimport android.content.Context\nimport androidx.hilt.work.HiltWorkerFactory\nimport androidx.work.Configuration\nimport com.google.android.material.color.DynamicColors\nimport com.shicheeng.copymanga.server.work.DetectMangaUpdateWork\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.ThemeMode\nimport com.shicheeng.copymanga.util.setSystemNightMode\nimport dagger.hilt.android.HiltAndroidApp\nimport javax.inject.Inject\n\n@HiltAndroidApp\nclass MyApp : Application(), Configuration.Provider {\n\n    companion object {\n        lateinit var appContext: Context\n    }\n\n    @Inject\n    lateinit var workerFactory: HiltWorkerFactory\n    private lateinit var notificationManager: NotificationManager\n\n    @Inject\n    lateinit var settingPref: SettingPref\n\n    override val workManagerConfiguration: Configuration\n        get() = Configuration.Builder()\n            .setWorkerFactory(workerFactory)\n            .build()\n\n\n    override fun onCreate() {\n        super.onCreate()\n        notificationManager = applicationContext\n            .getSystemService(NotificationManager::class.java)\n        DynamicColors.applyToActivitiesIfAvailable(this)\n        appContext = applicationContext\n        bindNotification()\n        val themeMode = ThemeMode.valueOf(settingPref.appThemeMode)\n        setSystemNightMode(themeMode)\n    }\n\n    private fun bindNotification() {\n        val name = getString(R.string.update_manga)\n        val importance = NotificationManager.IMPORTANCE_DEFAULT\n        val mChannel = NotificationChannel(\n            /* id = */ DetectMangaUpdateWork.DETECT_UPDATE_CHANELLE,\n            /* name = */ name,\n            /* importance = */ importance\n        )\n        notificationManager.createNotificationChannel(mChannel)\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/app/AppAttachCompatActivity.kt",
    "content": "package com.shicheeng.copymanga.app\n\nimport android.os.Bundle\nimport android.view.View\nimport androidx.appcompat.app.AppCompatActivity\nimport androidx.core.graphics.Insets\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowCompat\nimport androidx.core.view.WindowInsetsCompat\n\nopen class AppAttachCompatActivity : AppCompatActivity() {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        WindowCompat.setDecorFitsSystemWindows(window, false)\n    }\n\n\n    inline fun windowsInsets(\n        root: View,\n        crossinline update: Insets.(v: View, gestureInsets: Insets) -> Unit,\n    ) {\n        ViewCompat.setOnApplyWindowInsetsListener(root) { view: View, windowInsetsCompat: WindowInsetsCompat ->\n            val insets = windowInsetsCompat.getInsets(WindowInsetsCompat.Type.systemBars())\n            val systemGestureInsets =\n                windowInsetsCompat.getInsets(WindowInsetsCompat.Type.systemGestures())\n            update(insets, view, systemGestureInsets)\n            WindowInsetsCompat.Builder()\n                .setInsets(WindowInsetsCompat.Type.systemBars(), Insets.NONE)\n                .build()\n        }\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/app/BaseFragment.kt",
    "content": "package com.shicheeng.copymanga.app\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.core.graphics.Insets\nimport androidx.core.view.ViewCompat\nimport androidx.core.view.WindowInsetsCompat\nimport androidx.fragment.app.Fragment\nimport androidx.viewbinding.ViewBinding\n\nabstract class BaseFragment<VB : ViewBinding> : Fragment(), View.OnAttachStateChangeListener {\n\n    private var _binding: VB? = null\n    protected val binding: VB get() = _binding!!\n\n    override fun onCreateView(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n        savedInstanceState: Bundle?,\n    ): View {\n        _binding = onViewBindingIn(inflater, container)\n        binding.root.addOnAttachStateChangeListener(this)\n        return binding.root\n    }\n\n    override fun onViewAttachedToWindow(v: View) {\n        val insetsCompat = ViewCompat.getRootWindowInsets(v)\n        val systemBarInsets = insetsCompat?.getInsets(WindowInsetsCompat.Type.systemBars())\n        onFragmentInsets(systemBarInsets, v)\n    }\n\n    override fun onViewDetachedFromWindow(v: View) {\n\n    }\n\n    abstract fun onFragmentInsets(systemBarInsets: Insets?, view: View)\n\n    abstract fun onViewBindingIn(inflater: LayoutInflater, container: ViewGroup?): VB\n\n    override fun onDestroy() {\n        _binding = null\n        super.onDestroy()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/dao/MangaLoginDao.kt",
    "content": "package com.shicheeng.copymanga.dao\n\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Query\nimport androidx.room.Upsert\nimport com.shicheeng.copymanga.data.login.LocalLoginDataModel\nimport kotlinx.coroutines.flow.Flow\n\n@Dao\ninterface MangaLoginDao {\n\n    @Upsert\n    suspend fun updateOrInsertLoginData(localLoginDataModel: LocalLoginDataModel)\n\n    @Query(\"SELECT * FROM LocalLoginDataModel\")\n    fun getLoginData(): Flow<List<LocalLoginDataModel>>\n\n    @Query(\"SELECT * FROM LocalLoginDataModel\")\n    suspend fun getLoginDataAsync(): List<LocalLoginDataModel>\n\n    @Query(\"SELECT * FROM LocalLoginDataModel where userID = :userID LIMIT 1\")\n    fun getLoginDataByUserId(userID: String): Flow<LocalLoginDataModel>\n\n    @Query(\"SELECT * FROM LocalLoginDataModel where userID = :userID LIMIT 1\")\n    suspend fun getLoginDataByUserIdSafety(userID: String?): LocalLoginDataModel?\n\n    @Upsert\n    suspend fun updateOrInsertLoginData(vararg localLoginDataModels: LocalLoginDataModel)\n\n    @Query(\"SELECT token FROM LocalLoginDataModel where userID = :uuid LIMIT 1\")\n    fun getCurrentToken(uuid: String): String\n\n    @Query(\"SELECT isExpired FROM LocalLoginDataModel where userID = :uuid LIMIT 1\")\n    fun isExpired(uuid: String): Boolean\n\n    @Query(\"SELECT isExpired FROM LocalLoginDataModel where userID = :uuid LIMIT 1\")\n    fun isExpiredFlow(uuid: String): Flow<Boolean>\n\n\n    @Delete\n    suspend fun deleteLoginData(localLoginDataModel: LocalLoginDataModel)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/dao/MangeLocalHistoryDao.kt",
    "content": "package com.shicheeng.copymanga.dao\n\nimport androidx.room.*\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport kotlinx.coroutines.flow.Flow\n\n@Dao\ninterface MangeLocalHistoryDao {\n\n    @Query(\"SELECT * FROM manga_history_key ORDER by time DESC\")\n    fun getAllHistory(): Flow<List<MangaHistoryDataModel>>\n\n    @Query(\"SELECT * FROM manga_history_key ORDER by time DESC\")\n    suspend fun fetchTotalManga(): List<MangaHistoryDataModel>\n\n    @Query(\"SELECT * FROM manga_history_key WHERE pathWord LIKE :pathWord LIMIT 1\")\n    suspend fun getHistoryForInfoByPathWord(pathWord: String): MangaHistoryDataModel?\n\n    @Query(\"SELECT * FROM manga_history_key WHERE pathWord LIKE :pathWord LIMIT 1\")\n    fun fetchHistoryByPathWordInFlow(pathWord: String): Flow<MangaHistoryDataModel?>\n\n    @Transaction\n    @Query(\"SELECT * FROM manga_history_key WHERE pathWord = :pathWord LIMIT 1\")\n    suspend fun getMangaByPathWord(pathWord: String): LocalSavableMangaModel?\n\n    @Query(\"SELECT * FROM LocalChapter WHERE comicPathWord = :pathWord\")\n    suspend fun fetchMangaChaptersByPathWord(pathWord: String): List<LocalChapter>?\n\n    @Query(\"SELECT * FROM LocalChapter WHERE comicPathWord = :pathWord\")\n    fun fetchMangaChaptersByPathWordFlow(pathWord: String): Flow<List<LocalChapter>?>\n\n    @Insert(onConflict = OnConflictStrategy.IGNORE)\n    suspend fun addLocal(manga: MangaHistoryDataModel)\n\n    @Upsert\n    suspend fun addLocalChapter(chapter: LocalChapter)\n\n    @Upsert\n    suspend fun addLocalChapter(vararg chapter: LocalChapter)\n\n    @Upsert\n    suspend fun updateLocal(manga: MangaHistoryDataModel)\n\n    @Query(\"DELETE FROM manga_history_key\")\n    suspend fun deleteAllHistory()\n\n    @Delete\n    suspend fun deleteSingle(manga: MangaHistoryDataModel)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/dao/SearchHistoryDao.kt",
    "content": "package com.shicheeng.copymanga.dao\n\nimport androidx.room.Dao\nimport androidx.room.Delete\nimport androidx.room.Query\nimport androidx.room.Upsert\nimport com.shicheeng.copymanga.data.searchhistory.SearchHistory\nimport kotlinx.coroutines.flow.Flow\n\n@Dao\ninterface SearchHistoryDao {\n\n    @Query(\"SELECT * FROM SearchHistory ORDER by time DESC\")\n    fun loadWordHistory(): Flow<List<SearchHistory>>\n\n    @Delete\n    suspend fun detectSearchedWordHistory(searchHistory: SearchHistory)\n\n    @Query(\"DELETE FROM SearchHistory\")\n    suspend fun delThing()\n\n    @Upsert\n    suspend fun upsertWord(searchHistory: SearchHistory)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/BannerList.java",
    "content": "package com.shicheeng.copymanga.data;\n\nimport com.google.gson.JsonObject;\n\npublic class BannerList {\n    private JsonObject jsonObject;\n\n    public void setJsonObject(JsonObject jsonObject) {\n        this.jsonObject = jsonObject;\n    }\n\n    public JsonObject getJsonObject() {\n        return jsonObject;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/ChipTextBean.kt",
    "content": "package com.shicheeng.copymanga.data\n\nimport androidx.annotation.DrawableRes\n\ndata class ChipTextBean(\n    var text: String,\n    var pathWord: String,\n    @DrawableRes val ids: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/DataBannerBean.java",
    "content": "package com.shicheeng.copymanga.data;\n\npublic class DataBannerBean {\n    private String bannerImageUrl;\n    private String bannerBrief;\n    private String uuidManga;\n\n    public DataBannerBean() {\n    }\n\n    public String getBannerBrief() {\n        return bannerBrief;\n    }\n\n    public void setBannerBrief(String bannerBrief) {\n        this.bannerBrief = bannerBrief;\n    }\n\n    public String getBannerImageUrl() {\n        return bannerImageUrl;\n    }\n\n    public void setBannerImageUrl(String bannerImageUrl) {\n        this.bannerImageUrl = bannerImageUrl;\n    }\n\n    public String getUuidManga() {\n        return uuidManga;\n    }\n\n    public void setUuidManga(String uuidManga) {\n        this.uuidManga = uuidManga;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/ListBeanManga.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class ListBeanManga(\n    var nameManga: String,\n    var authorManga: String,\n    var urlCoverManga: String,\n    var pathWordManga: String,\n) {\n    constructor() : this(\n        nameManga = \"\",\n        authorManga = \"\",\n        urlCoverManga = \"\",\n        pathWordManga = \"\"\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/LocalManga.kt",
    "content": "package com.shicheeng.copymanga.data\n\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport java.io.File\n\ndata class LocalManga(\n    val localSavableMangaModel: LocalSavableMangaModel,\n    val file:File,\n)\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MainPageDataModel.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class MainPageDataModel(\n    val listBanner: List<DataBannerBean>,\n    val listRecommend: List<ListBeanManga>,\n    val listRankDay: List<MangaRankMiniModel>,\n    val listRankWeek: List<MangaRankMiniModel>,\n    val listRankMonth: List<MangaRankMiniModel>,\n    val listHot: List<ListBeanManga>,\n    val listNewest: List<ListBeanManga>,\n    val listFinished: List<ListBeanManga>,\n    val topicList:List<MainTopicDataModel>\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MainTopicDataModel.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class MainTopicDataModel(\n    val name: String,\n    val type: Int,\n    val brief: String,\n    val pathWord: String,\n    val coverUrl: String,\n    val datetimeCreated: String,\n    val period: String,\n    val journal: String,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MangaGenernal.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class MangaInfoData(\n    val title: String,\n    val alias: String,\n    val mangaDetail: String,\n    val mangaStatus: String,\n    val authorList: String,\n    val themeList: List<ChipTextBean>,\n    val mangaCoverUrl: String,\n    val mangaUUID: String,\n    val mangaStatusId: Int,\n    val mangaRegion: String,\n    val mangaLastUpdate: String,\n    val mangaPopularNumber: String,\n)\n\ndata class MangaRankMiniModel(\n    val name: String,\n    val author: String,\n    val urlCover: String,\n    val popular: String,\n    val riseHot: String,\n    val pathWord: String,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MangaHistoryDataModel.kt",
    "content": "package com.shicheeng.copymanga.data\n\nimport androidx.room.Entity\nimport androidx.room.PrimaryKey\nimport androidx.room.TypeConverters\nimport com.shicheeng.copymanga.data.info.Author\nimport com.shicheeng.copymanga.database.AuthorToStringConvert\nimport com.shicheeng.copymanga.database.StringToBeanConvert\n\n@TypeConverters(StringToBeanConvert::class, AuthorToStringConvert::class)\n@Entity(tableName = \"manga_history_key\")\ndata class MangaHistoryDataModel(\n    val name: String,\n    val time: Long,\n    val alias: String?,\n    val url: String,\n    @PrimaryKey val pathWord: String,\n    val comicUUID:String,\n    val nameChapter: String,\n    val positionChapter: Int,\n    val positionPage: Int,\n    val readerModeId: Int,\n    val mangaDetail: String,\n    val mangaStatus: String,\n    val authorList: List<Author>,\n    val themeList: List<MangaSortBean>,\n    val mangaStatusId: Int,\n    val mangaRegion: String,\n    val mangaLastUpdate: String,\n    val mangaPopularNumber: String,\n    val isSubscribe: Boolean,\n)\n\ndata class MangaState(\n    val uuid: String,\n    val page: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MangaInfoChapterDataBean.kt",
    "content": "package com.shicheeng.copymanga.data\n\nimport android.os.Parcelable\nimport kotlinx.parcelize.IgnoredOnParcel\nimport kotlinx.parcelize.Parcelize\n\n@Parcelize\ndata class MangaInfoChapterDataBean(\n    val chapterTitle: String,\n    val chapterTime: String,\n    val uuidText: String,\n    val readerProgress: Int?,\n    val isDownloading: Boolean = false,\n    val pathWord: String,\n    val isSaved: Boolean = false,\n) : Parcelable {\n\n    @IgnoredOnParcel\n    var isSelect: Boolean = false\n\n    fun toDownloadChapter(): MangaDownloadChapterInfoModel {\n        return MangaDownloadChapterInfoModel(chapterTitle, uuidText, pathWord)\n    }\n\n    fun toMangaState(): MangaState {\n        return MangaState(uuidText, readerProgress ?: 0)\n    }\n\n}\n\n@Parcelize\ndata class LastMangaDownload(\n    /**\n     * 漫画名字\n     */\n    val mangaName: String,\n    val coverUrl: String,\n    val list: List<MangaDownloadChapterInfoModel>,\n) :\n    Parcelable\n\n@Parcelize\ndata class MangaDownloadChapterInfoModel(\n    val chapterTitle: String,\n    /**\n     * 漫画章节的UUID\n     */\n    val uuidText: String,\n    /**\n     * 漫画的pathWord\n     */\n    val pathWord: String,\n) : Parcelable {\n\n    override fun hashCode(): Int {\n        return pathWord.hashCode() + uuidText.length + chapterTitle.hashCode()\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as MangaDownloadChapterInfoModel\n\n        if (chapterTitle != other.chapterTitle) return false\n        if (uuidText != other.uuidText) return false\n        if (pathWord != other.pathWord) return false\n\n        return true\n    }\n\n\n}\n\n\n@Parcelize\ndata class MangaDownloads(\n    val urlList: List<String>,\n    val wordsList: List<Int>,\n) : Parcelable {\n    override fun hashCode(): Int {\n        return urlList.size + wordsList.size\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as MangaDownloads\n\n        if (urlList != other.urlList) return false\n        if (wordsList != other.wordsList) return false\n\n        return true\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MangaReadInformation.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class MangaReadInformation(\n    val subtitle: String?,\n    val time: String?,\n    val size: Int?,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MangaReaderPage.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class MangaReaderPage(\n    val url: String,\n    val uuid: String?,\n    val index: Int,\n    val urlHashCode: Int = url.hashCode(),\n) {\n    override fun hashCode(): Int {\n        return url.hashCode() + uuid.hashCode() * 212\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as MangaReaderPage\n\n        if (url != other.url) return false\n        if (uuid != other.uuid) return false\n        if (index != other.index) return false\n        if (urlHashCode != other.urlHashCode) return false\n\n        return true\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/MangaSortBean.java",
    "content": "package com.shicheeng.copymanga.data;\n\nimport android.os.Parcel;\nimport android.os.Parcelable;\n\nimport androidx.annotation.NonNull;\n\npublic class MangaSortBean implements Parcelable {\n    private String pathName;\n    private String pathWord;\n\n    public MangaSortBean(String pathName, String pathWord) {\n        this.pathName = pathName;\n        this.pathWord = pathWord;\n    }\n\n    public MangaSortBean() {\n\n    }\n\n    protected MangaSortBean(Parcel in) {\n        pathName = in.readString();\n        pathWord = in.readString();\n    }\n\n    public static final Creator<MangaSortBean> CREATOR = new Creator<MangaSortBean>() {\n        @Override\n        public MangaSortBean createFromParcel(Parcel in) {\n            return new MangaSortBean(in);\n        }\n\n        @Override\n        public MangaSortBean[] newArray(int size) {\n            return new MangaSortBean[size];\n        }\n    };\n\n    public String getPathWord() {\n        return pathWord;\n    }\n\n    public void setPathWord(String pathWord) {\n        this.pathWord = pathWord;\n    }\n\n\n    public String getPathName() {\n        return pathName;\n    }\n\n    public void setPathName(String pathName) {\n        this.pathName = pathName;\n    }\n\n    @Override\n    public int describeContents() {\n        return 0;\n    }\n\n    @Override\n    public void writeToParcel(@NonNull Parcel dest, int flags) {\n        dest.writeString(pathName);\n        dest.writeString(pathWord);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/PersonalDataModel.kt",
    "content": "package com.shicheeng.copymanga.data\n\nimport android.net.Uri\nimport android.os.Parcelable\nimport androidx.annotation.StringRes\nimport kotlinx.parcelize.Parcelize\n\ndata class PersonalDataModel(@StringRes val title: Int, val list: List<Any>)\n\n@Parcelize\ndata class PersonalInnerDataModel(\n    val name: String,\n    val url: Uri?,\n    val pathWord: String?,\n) : Parcelable\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/ReaderDataModels.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class ReaderContent(val list: List<MangaReaderPage>, val state: MangaState?)\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/ReaderState.kt",
    "content": "package com.shicheeng.copymanga.data\n\ndata class ReaderState(\n    val mangaName:String?,\n    val chapterName: String?,\n    val subTime: String?,\n    val uuid: String?,\n    val totalPage: Int,\n    val currentPage: Int,\n    val chapterPosition: Int,\n){\n    fun isSliderAvailable(): Boolean {\n        return  totalPage > 1 && currentPage < totalPage\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/UpdateMetadata.kt",
    "content": "package com.shicheeng.copymanga.data\n\n\ndata class VersionId(\n    val major: Int,\n    val minor: Int,\n    val build: Int,\n    val type: String,\n    val typeRNum: Int,\n) : Comparable<VersionId> {\n\n    override fun compareTo(other: VersionId): Int {\n        var diff = major.compareTo(other.major)\n        if (diff != 0) return diff\n        diff = minor.compareTo(other.minor)\n        if (diff != 0) return diff\n        diff = build.compareTo(other.build)\n        if (diff != 0) return diff\n        diff = typeCompareWeight(type).compareTo(typeCompareWeight(other.type))\n        if (diff != 0) return diff\n        return typeRNum.compareTo(other.typeRNum)\n    }\n\n    private fun typeCompareWeight(type: String): Int = when (type) {\n        \"FIX\" -> 8\n        \"PATCH\" -> 4\n        \"\" -> 2\n        else -> 0\n    }\n\n}\n\ndata class VersionUnit(\n    val id: Long,\n    val htmlUrl: String,\n    val versionName: String,\n    val apkUrl: String,\n    val apkSize: Long,\n    val description: String,\n    val time: String,\n    val versionId: VersionId = versionId(versionName),\n)\n\nfun versionId(nameTag: String): VersionId {\n    val part = nameTag.substringBefore(\"-\").split(\".\")\n    val name = nameTag.substringAfter(\"-\", \"\")\n    return VersionId(\n        major = part.getOrNull(0)?.toIntOrNull() ?: 0,\n        minor = part.getOrNull(1)?.toIntOrNull() ?: 0,\n        build = part.getOrNull(2)?.toIntOrNull() ?: 0,\n        type = name.filter(Char::isUpperCase),\n        typeRNum = name.filter(Char::isDigit).toIntOrNull() ?: 0\n    )\n}\n\nval VersionId.isNormal get() = type.isEmpty()"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/authormanga/Author.kt",
    "content": "package com.shicheeng.copymanga.data.authormanga\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/authormanga/AuthorMangaItem.kt",
    "content": "package com.shicheeng.copymanga.data.authormanga\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class AuthorMangaItem(\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_updated\")\n    val datetimeUpdated: String,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"free_type\")\n    val freeType: FreeType,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"theme\")\n    val theme: List<Any>\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/authormanga/AuthorsMangaDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.authormanga\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class AuthorsMangaDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/authormanga/FreeType.kt",
    "content": "package com.shicheeng.copymanga.data.authormanga\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class FreeType(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/authormanga/Results.kt",
    "content": "package com.shicheeng.copymanga.data.authormanga\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<AuthorMangaItem>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/chapter/Chapter.kt",
    "content": "package com.shicheeng.copymanga.data.chapter\n\n\nimport androidx.annotation.Keep\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Chapter(\n    @Json(name = \"comic_id\")\n    val comicId: String,\n    @Json(name = \"comic_path_word\")\n    val comicPathWord: String,\n    @Json(name = \"count\")\n    val count: Int,\n    var datetime_created: String,\n    @Json(name = \"group_id\")\n    val groupId: Any?,\n    @Json(name = \"group_path_word\")\n    val groupPathWord: String,\n    @Json(name = \"img_type\")\n    val imgType: Int,\n    @Json(name = \"index\")\n    val index: Int,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"news\")\n    val news: String,\n    @Json(name = \"next\")\n    val next: String?,\n    @Json(name = \"ordered\")\n    val ordered: Int,\n    @Json(name = \"prev\")\n    val prev: String?,\n    @Json(name = \"size\")\n    val size: Int,\n    @Json(name = \"type\")\n    val type: Int,\n    @Json(name = \"uuid\")\n    val uuid: String,\n)\n\nfun Chapter.toLocalChapter(\n    readIndex: Int,\n    isReadInProgress: Boolean,\n    isDownloaded: Boolean,\n    isReadFinish: Boolean,\n): LocalChapter {\n    return LocalChapter(\n        comicId = comicId,\n        comicPathWord = comicPathWord,\n        count = count,\n        datetime_created = datetime_created,\n        groupId = groupId as String?,\n        groupPathWord = groupPathWord,\n        imgType = imgType,\n        index = index,\n        readIndex = readIndex,\n        isReadProgress = isReadInProgress,\n        name = name,\n        news = news,\n        next = next,\n        ordered = ordered,\n        prev = prev,\n        size = size,\n        type = type,\n        uuid = uuid,\n        isDownloaded = isDownloaded,\n        isReadFinish = isReadFinish\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/chapter/ChapterDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.chapter\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class ChapterDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/chapter/Results.kt",
    "content": "package com.shicheeng.copymanga.data.chapter\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<Chapter>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/collect/ComicCollectDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.collect\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class ComicCollectDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Any?\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/commentpush/CommentPushDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.commentpush\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class CommentPushDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Any?\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/downloadmodel/DownloadUiDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.downloadmodel\n\nimport android.text.format.DateUtils\nimport androidx.work.WorkInfo\nimport androidx.work.Worker\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport java.lang.invoke.MethodHandles.Lookup\nimport java.util.UUID\n\ndata class DownloadUiDataModel(\n    val localSavableMangaModel: LocalSavableMangaModel,\n    val pathWord: String,\n    val progress: Int,\n    val max: Int,\n    val error: String?,\n    val isIndeterminate: Boolean,\n    val isPause: Boolean,\n    val isStopped: Boolean,\n    val workerState: WorkInfo.State,\n    val timeStamp: Long,\n    val totalChapter: Int,\n    val id: UUID,\n    val eta: Long,\n) : Comparable<DownloadUiDataModel> {\n\n    val percent: Float\n        get() = if (max > 0) progress / max.toFloat() else 0f\n\n    val hasEta: Boolean\n        get() = workerState == WorkInfo.State.RUNNING && !isPause && eta > 0L\n\n    override fun compareTo(other: DownloadUiDataModel): Int {\n        return timeStamp.compareTo(other.timeStamp)\n    }\n\n    val canResume: Boolean\n        get() = workerState == WorkInfo.State.RUNNING && isPause\n\n    fun getEtaString(): CharSequence? = if (hasEta) {\n        DateUtils.getRelativeTimeSpanString(\n            eta,\n            System.currentTimeMillis(),\n            DateUtils.SECOND_IN_MILLIS,\n        )\n    } else {\n        null\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/finished/Author.kt",
    "content": "package com.shicheeng.copymanga.data.finished\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/finished/FinishedMangaDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.finished\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class FinishedMangaDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/finished/FreeType.kt",
    "content": "package com.shicheeng.copymanga.data.finished\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class FreeType(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/finished/Item.kt",
    "content": "package com.shicheeng.copymanga.data.finished\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Item(\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_updated\")\n    val datetimeUpdated: String?,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"free_type\")\n    val freeType: FreeType,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"theme\")\n    val theme: List<Theme>,\n) {\n\n    fun authorReformation() = buildString {\n        author.forEachIndexed { index, a ->\n            append(a.name)\n            if (index != author.lastIndex) {\n                append(\"，\")\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/finished/Results.kt",
    "content": "package com.shicheeng.copymanga.data.finished\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<Item>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/finished/Theme.kt",
    "content": "package com.shicheeng.copymanga.data.finished\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Theme(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Author.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Comic.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Comic(\n    @Json(name = \"alias\")\n    val alias: String?,\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"brief\")\n    val brief: String,\n    @Json(name = \"clubs\")\n    val clubs: List<Any>,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_updated\")\n    val datetimeUpdated: String?,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"free_type\")\n    val freeType: FreeType,\n    @Json(name = \"img_type\")\n    val imgType: Int,\n    @Json(name = \"last_chapter\")\n    val lastChapter: LastChapter,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"parodies\")\n    val parodies: List<Any>,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"reclass\")\n    val reclass: Reclass,\n    @Json(name = \"region\")\n    val region: Region,\n    @Json(name = \"restrict\")\n    val restrict: Restrict,\n    @Json(name = \"seo_baidu\")\n    val seoBaidu: String,\n    @Json(name = \"status\")\n    val status: Status,\n    @Json(name = \"theme\")\n    val theme: List<Theme>,\n    @Json(name = \"uuid\")\n    val uuid: String,\n){\n\n    fun authorReformation() = buildString {\n        author.forEachIndexed { index, a ->\n            append(a.name)\n            if (index != author.lastIndex) {\n                append(\"，\")\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Default.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Default(\n    @Json(name = \"count\")\n    val count: Int,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/FreeType.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class FreeType(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Groups.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Groups(\n    @Json(name = \"default\")\n    val default: Default?\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/LastChapter.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class LastChapter(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"uuid\")\n    val uuid: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/MangaInfoDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@JsonClass(generateAdapter = true)\ndata class MangaInfoDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Reclass.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Reclass(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Region.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Region(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Restrict.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Restrict(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Results.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"comic\")\n    val comic: Comic,\n    @Json(name = \"groups\")\n    val groups: Groups,\n    @Json(name = \"is_lock\")\n    val isLock: Boolean,\n    @Json(name = \"is_login\")\n    val isLogin: Boolean,\n    @Json(name = \"is_mobile_bind\")\n    val isMobileBind: Boolean,\n    @Json(name = \"is_vip\")\n    val isVip: Boolean,\n    @Json(name = \"popular\")\n    val popular: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Status.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Status(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/info/Theme.kt",
    "content": "package com.shicheeng.copymanga.data.info\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Theme(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/local/Chapter.kt",
    "content": "package com.shicheeng.copymanga.data.local\n\nimport androidx.room.Entity\nimport androidx.room.PrimaryKey\nimport com.shicheeng.copymanga.data.MangaState\n\n\n@Entity\ndata class LocalChapter(\n    val comicId: String,\n    val comicPathWord: String,\n    val count: Int,\n    var datetime_created: String,\n    val groupId: String?,\n    val groupPathWord: String,\n    val imgType: Int,\n    val index: Int,\n    val readIndex: Int,\n    val isReadProgress: Boolean,\n    val name: String,\n    val news: String,\n    val next: String?,\n    val ordered: Int,\n    val prev: String?,\n    val size: Int,\n    val type: Int,\n    @PrimaryKey val uuid: String,\n    val isDownloaded: Boolean,\n    val isReadFinish: Boolean,\n)\n\nfun LocalChapter.toMangaState(): MangaState {\n    return MangaState(\n        uuid = uuid,\n        page = if (isReadFinish) 0 else readIndex\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/local/LocalSavableMangaModel.kt",
    "content": "package com.shicheeng.copymanga.data.local\n\nimport androidx.room.Embedded\nimport androidx.room.Relation\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\n\n\ndata class LocalSavableMangaModel(\n    @Embedded val mangaHistoryDataModel: MangaHistoryDataModel,\n    @Relation(\n        parentColumn = \"pathWord\",\n        entityColumn = \"comicPathWord\"\n    )\n    val list: List<LocalChapter>,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/lofininfo/LoginInfoDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.lofininfo\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class LoginInfoDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/lofininfo/Results.kt",
    "content": "package com.shicheeng.copymanga.data.lofininfo\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"ads_vip_end\")\n    val adsVipEnd: Any?,\n    @Json(name = \"avatar\")\n    val avatar: String,\n    @Json(name = \"b_sstv\")\n    val bSstv: Boolean,\n    @Json(name = \"b_verify_email\")\n    val bVerifyEmail: Boolean,\n    @Json(name = \"cartoon_vip\")\n    val cartoonVip: Int,\n    @Json(name = \"cartoon_vip_end\")\n    val cartoonVipEnd: Any?,\n    @Json(name = \"cartoon_vip_start\")\n    val cartoonVipStart: Any?,\n    @Json(name = \"close_report\")\n    val closeReport: Boolean,\n    @Json(name = \"comic_vip\")\n    val comicVip: Int,\n    @Json(name = \"comic_vip_end\")\n    val comicVipEnd: Any?,\n    @Json(name = \"comic_vip_start\")\n    val comicVipStart: Any?,\n    @Json(name = \"datetime_created\")\n    val datetimeCreated: String,\n    @Json(name = \"day_downloads\")\n    val dayDownloads: Int,\n    @Json(name = \"day_downloads_refresh\")\n    val dayDownloadsRefresh: String,\n    @Json(name = \"downloads\")\n    val downloads: Int,\n    @Json(name = \"email\")\n    val email: String,\n    @Json(name = \"invite_code\")\n    val inviteCode: Any?,\n    @Json(name = \"invited\")\n    val invited: Any?,\n    @Json(name = \"is_authenticated\")\n    val isAuthenticated: Boolean,\n    @Json(name = \"mobile\")\n    val mobile: Any?,\n    @Json(name = \"mobile_region\")\n    val mobileRegion: Any?,\n    @Json(name = \"nickname\")\n    val nickname: String,\n    @Json(name = \"point\")\n    val point: Int,\n    @Json(name = \"reward_downloads\")\n    val rewardDownloads: Int,\n    @Json(name = \"scy_answer\")\n    val scyAnswer: Boolean,\n    @Json(name = \"user_id\")\n    val userId: String,\n    @Json(name = \"username\")\n    val username: String,\n    @Json(name = \"vip_downloads\")\n    val vipDownloads: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/login/LocalLoginDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.login\n\nimport androidx.room.Entity\nimport androidx.room.PrimaryKey\nimport com.shicheeng.copymanga.data.lofininfo.LoginInfoDataModel\n\n@Entity\ndata class LocalLoginDataModel(\n    val avatarImageUrl: String,\n    val nikeName: String,\n    val userName: String,\n    val token: String,\n    @PrimaryKey val userID: String,\n    val email: String,\n    val selected: Boolean,\n    val isExpired: Boolean,\n)\n\nfun LoginDataModel.toLoginDataModel(isSelected: Boolean = false) = LocalLoginDataModel(\n    nikeName = results.nickname,\n    userName = results.username,\n    email = results.email,\n    token = results.token,\n    userID = results.userId,\n    avatarImageUrl = results.avatar,\n    selected = isSelected,\n    isExpired = false\n)\n\nfun LoginInfoDataModel.toLoginDataModel(\n    localLoginDataModel: LocalLoginDataModel,\n    isSelected: Boolean = false,\n    isExpired: Boolean,\n) = LocalLoginDataModel(\n    nikeName = results.nickname,\n    userName = results.username,\n    email = results.email,\n    token = localLoginDataModel.token,\n    userID = results.userId,\n    avatarImageUrl = results.avatar,\n    selected = isSelected,\n    isExpired = isExpired\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/login/LoginDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.login\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class LoginDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/login/Results.kt",
    "content": "package com.shicheeng.copymanga.data.login\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"ads_vip_end\")\n    val adsVipEnd: Any?,\n    @Json(name = \"avatar\")\n    val avatar: String,\n    @Json(name = \"b_sstv\")\n    val bSstv: Boolean,\n    @Json(name = \"b_verify_email\")\n    val bVerifyEmail: Boolean,\n    @Json(name = \"cartoon_vip\")\n    val cartoonVip: Int,\n    @Json(name = \"cartoon_vip_end\")\n    val cartoonVipEnd: Any?,\n    @Json(name = \"cartoon_vip_start\")\n    val cartoonVipStart: Any?,\n    @Json(name = \"close_report\")\n    val closeReport: Boolean,\n    @Json(name = \"comic_vip\")\n    val comicVip: Int,\n    @Json(name = \"comic_vip_end\")\n    val comicVipEnd: Any?,\n    @Json(name = \"comic_vip_start\")\n    val comicVipStart: Any?,\n    @Json(name = \"datetime_created\")\n    val datetimeCreated: String,\n    @Json(name = \"downloads\")\n    val downloads: Int,\n    @Json(name = \"email\")\n    val email: String,\n    @Json(name = \"invite_code\")\n    val inviteCode: Any?,\n    @Json(name = \"invited\")\n    val invited: Any?,\n    @Json(name = \"is_authenticated\")\n    val isAuthenticated: Boolean,\n    @Json(name = \"mobile\")\n    val mobile: Any?,\n    @Json(name = \"mobile_region\")\n    val mobileRegion: Any?,\n    @Json(name = \"nickname\")\n    val nickname: String,\n    @Json(name = \"point\")\n    val point: Int,\n    @Json(name = \"reward_downloads\")\n    val rewardDownloads: Int,\n    @Json(name = \"scy_answer\")\n    val scyAnswer: Boolean,\n    @Json(name = \"token\")\n    val token: String,\n    @Json(name = \"user_id\")\n    val userId: String,\n    @Json(name = \"username\")\n    val username: String,\n    @Json(name = \"vip_downloads\")\n    val vipDownloads: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/logininfoshort/Gender.kt",
    "content": "package com.shicheeng.copymanga.data.logininfoshort\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Gender(\n    @Json(name = \"key\")\n    val key: Int,\n    @Json(name = \"value\")\n    val value: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/logininfoshort/GenderX.kt",
    "content": "package com.shicheeng.copymanga.data.logininfoshort\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class GenderX(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/logininfoshort/Info.kt",
    "content": "package com.shicheeng.copymanga.data.logininfoshort\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Info(\n    @Json(name = \"avatar\")\n    val avatar: String,\n    @Json(name = \"avatar_rp\")\n    val avatarRp: String,\n    @Json(name = \"gender\")\n    val gender: GenderX,\n    @Json(name = \"invite_code\")\n    val inviteCode: Any?,\n    @Json(name = \"mobile\")\n    val mobile: Any?,\n    @Json(name = \"mobile_region\")\n    val mobileRegion: Any?,\n    @Json(name = \"nickname\")\n    val nickname: String,\n    @Json(name = \"username\")\n    val username: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/logininfoshort/LoginInfoShortDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.logininfoshort\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class LoginInfoShortDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/logininfoshort/Results.kt",
    "content": "package com.shicheeng.copymanga.data.logininfoshort\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"genders\")\n    val genders: List<Gender>,\n    @Json(name = \"info\")\n    val info: Info\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacomment/MangaCommentDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.mangacomment\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class MangaCommentDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacomment/MangaCommentListItem.kt",
    "content": "package com.shicheeng.copymanga.data.mangacomment\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class MangaCommentListItem(\n    @Json(name = \"comment\")\n    val comment: String,\n    @Json(name = \"count\")\n    val count: Int,\n    @Json(name = \"create_at\")\n    val createAt: String,\n    @Json(name = \"id\")\n    val id: Int,\n    @Json(name = \"parent_id\")\n    val parentId: Any?,\n    @Json(name = \"parent_user_id\")\n    val parentUserId: Any?,\n    @Json(name = \"parent_user_name\")\n    val parentUserName: Any?,\n    @Json(name = \"user_avatar\")\n    val userAvatar: String,\n    @Json(name = \"user_id\")\n    val userId: String,\n    @Json(name = \"user_name\")\n    val userName: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacomment/Results.kt",
    "content": "package com.shicheeng.copymanga.data.mangacomment\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<MangaCommentListItem>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacontent/Chapter.kt",
    "content": "package com.shicheeng.copymanga.data.mangacontent\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Chapter(\n    @Json(name = \"comic_id\")\n    val comicId: String,\n    @Json(name = \"comic_path_word\")\n    val comicPathWord: String,\n    @Json(name = \"contents\")\n    val contents: List<Content>,\n    @Json(name = \"count\")\n    val count: Int,\n    @Json(name = \"datetime_created\")\n    val datetimeCreated: String,\n    @Json(name = \"group_id\")\n    val groupId: Any?,\n    @Json(name = \"group_path_word\")\n    val groupPathWord: String,\n    @Json(name = \"img_type\")\n    val imgType: Int,\n    @Json(name = \"index\")\n    val index: Int,\n    @Json(name = \"is_long\")\n    val isLong: Boolean,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"news\")\n    val news: String,\n    @Json(name = \"next\")\n    val next: String?,\n    @Json(name = \"ordered\")\n    val ordered: Int,\n    @Json(name = \"prev\")\n    val prev: String?,\n    @Json(name = \"size\")\n    val size: Int,\n    @Json(name = \"type\")\n    val type: Int,\n    @Json(name = \"uuid\")\n    val uuid: String,\n    @Json(name = \"words\")\n    val words: List<Int>\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacontent/Comic.kt",
    "content": "package com.shicheeng.copymanga.data.mangacontent\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Comic(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"restrict\")\n    val restrict: Restrict,\n    @Json(name = \"uuid\")\n    val uuid: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacontent/Content.kt",
    "content": "package com.shicheeng.copymanga.data.mangacontent\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Content(\n    @Json(name = \"url\")\n    val url: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacontent/MangaContentDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.mangacontent\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class MangaContentDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacontent/Restrict.kt",
    "content": "package com.shicheeng.copymanga.data.mangacontent\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Restrict(\n    @Json(name = \"display\")\n    val display: String,\n    @Json(name = \"value\")\n    val value: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/mangacontent/Results.kt",
    "content": "package com.shicheeng.copymanga.data.mangacontent\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"chapter\")\n    val chapter: Chapter,\n    @Json(name = \"comic\")\n    val comic: Comic,\n    @Json(name = \"is_lock\")\n    val isLock: Boolean,\n    @Json(name = \"is_login\")\n    val isLogin: Boolean,\n    @Json(name = \"is_mobile_bind\")\n    val isMobileBind: Boolean,\n    @Json(name = \"is_vip\")\n    val isVip: Boolean,\n    @Json(name = \"show_app\")\n    val showApp: Boolean\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/newsest/Author.kt",
    "content": "package com.shicheeng.copymanga.data.newsest\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/newsest/Comic.kt",
    "content": "package com.shicheeng.copymanga.data.newsest\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Comic(\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_updated\")\n    val datetimeUpdated: String,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"img_type\")\n    val imgType: Int,\n    @Json(name = \"last_chapter_name\")\n    val lastChapterName: String,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"theme\")\n    val theme: List<Any>,\n) {\n    fun authorReformation() = buildString {\n        author.forEachIndexed { index, a ->\n            append(a.name)\n            if (index != author.lastIndex) {\n                append(\"，\")\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/newsest/MangaBlock.kt",
    "content": "package com.shicheeng.copymanga.data.newsest\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class MangaBlock(\n    @Json(name = \"comic\")\n    val comic: Comic,\n    @Json(name = \"datetime_created\")\n    val datetimeCreated: String,\n    @Json(name = \"name\")\n    val name: String,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/newsest/NewestListDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.newsest\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class NewestListDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/newsest/Results.kt",
    "content": "package com.shicheeng.copymanga.data.newsest\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<MangaBlock>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/rank/Author.kt",
    "content": "package com.shicheeng.copymanga.data.rank\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/rank/Comic.kt",
    "content": "package com.shicheeng.copymanga.data.rank\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Comic(\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"img_type\")\n    val imgType: Int,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"theme\")\n    val theme: List<Any>,\n) {\n\n    fun authorThat() = buildString {\n        author.forEachIndexed { index: Int, authorIn: Author ->\n            append(authorIn.name)\n            if (index != author.lastIndex) {\n                append(\"，\")\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/rank/Item.kt",
    "content": "package com.shicheeng.copymanga.data.rank\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Item(\n    @Json(name = \"comic\")\n    val comic: Comic,\n    @Json(name = \"date_type\")\n    val dateType: Int,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"rise_num\")\n    val riseNum: Int,\n    @Json(name = \"rise_sort\")\n    val riseSort: Int,\n    @Json(name = \"sort\")\n    val sort: Int,\n    @Json(name = \"sort_last\")\n    val sortLast: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/rank/RankDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.rank\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class RankDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/rank/Results.kt",
    "content": "package com.shicheeng.copymanga.data.rank\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<Item>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/recommend/RecommendDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.recommend\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class RecommendDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results,\n) {\n    @Keep\n    @JsonClass(generateAdapter = true)\n    data class Results(\n        @Json(name = \"limit\")\n        val limit: Int,\n        @Json(name = \"list\")\n        val list: List<Item>,\n        @Json(name = \"offset\")\n        val offset: Int,\n        @Json(name = \"total\")\n        val total: Int,\n    ) {\n        @Keep\n        @JsonClass(generateAdapter = true)\n        data class Item(\n            @Json(name = \"comic\")\n            val comic: Comic,\n            @Json(name = \"type\")\n            val type: Int,\n        ) {\n            @Keep\n            @JsonClass(generateAdapter = true)\n            data class Comic(\n                @Json(name = \"author\")\n                val author: List<Author>,\n                @Json(name = \"cover\")\n                val cover: String,\n                @Json(name = \"females\")\n                val females: List<Any>,\n                @Json(name = \"img_type\")\n                val imgType: Int,\n                @Json(name = \"males\")\n                val males: List<Any>,\n                @Json(name = \"name\")\n                val name: String,\n                @Json(name = \"path_word\")\n                val pathWord: String,\n                @Json(name = \"popular\")\n                val popular: Int,\n                @Json(name = \"theme\")\n                val theme: List<Theme>,\n            ) {\n\n                fun authorReformation() = buildString {\n                    author.forEachIndexed { index, a ->\n                        append(a.name)\n                        if (index != author.lastIndex) {\n                            append(\"，\")\n                        }\n                    }\n                }\n\n                @Keep\n                @JsonClass(generateAdapter = true)\n                data class Author(\n                    @Json(name = \"name\")\n                    val name: String,\n                    @Json(name = \"path_word\")\n                    val pathWord: String,\n                )\n\n                @Keep\n                @JsonClass(generateAdapter = true)\n                data class Theme(\n                    @Json(name = \"name\")\n                    val name: String,\n                    @Json(name = \"path_word\")\n                    val pathWord: String,\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/search/Author.kt",
    "content": "package com.shicheeng.copymanga.data.search\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"alias\")\n    val alias: String?,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/search/Results.kt",
    "content": "package com.shicheeng.copymanga.data.search\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<SearchResultDataModel>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/search/SearchDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.search\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class SearchDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/search/SearchResultDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.search\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class SearchResultDataModel(\n    @Json(name = \"alias\")\n    val alias: String?,\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"img_type\")\n    val imgType: Int,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n) {\n\n    fun authorReformation() = buildString {\n        author.forEachIndexed { index, a ->\n            append(a.name)\n            if (index != author.lastIndex) {\n                append(\"，\")\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/searchhelpword/SearchTermWordDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.searchhelpword\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class SearchTermWordDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"data\")\n    val `data`: List<String>,\n    @Json(name = \"msg\")\n    val msg: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/searchhistory/SearchHistory.kt",
    "content": "package com.shicheeng.copymanga.data.searchhistory\n\nimport androidx.room.Entity\nimport androidx.room.PrimaryKey\n\n@Entity\ndata class SearchHistory(\n    @PrimaryKey\n    val word: String,\n    val time:Long,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/searchrecommend/Data.kt",
    "content": "package com.shicheeng.copymanga.data.searchrecommend\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Data(\n    @Json(name = \"title\")\n    val title: String,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/searchrecommend/SearchRecommendDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.searchrecommend\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class SearchRecommendDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"data\")\n    val `data`: List<Data>,\n    @Json(name = \"msg\")\n    val msg: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/sorttag/Ordering.kt",
    "content": "package com.shicheeng.copymanga.data.sorttag\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\n\n@Keep\ndata class Ordering(\n    @Json(name = \"datetime_updated\")\n    val datetimeUpdated: String,\n    @Json(name = \"popular\")\n    val popular: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/sorttag/Results.kt",
    "content": "package com.shicheeng.copymanga.data.sorttag\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\n\n@Keep\ndata class Results(\n    @Json(name = \"ordering\")\n    val ordering: Ordering,\n    @Json(name = \"theme\")\n    val theme: List<Theme>,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/sorttag/SortTagsDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.sorttag\n\n\nimport com.squareup.moshi.Json\nimport androidx.annotation.Keep\n\n@Keep\ndata class SortTagsDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/sorttag/Theme.kt",
    "content": "package com.shicheeng.copymanga.data.sorttag\n\n\nimport android.util.Log\nimport androidx.annotation.Keep\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.squareup.moshi.Json\n\n@Keep\ndata class Theme(\n    @Json(name = \"count\")\n    val count: Int,\n    @Json(name = \"initials\")\n    val initials: Int,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n) {\n    init {\n        Log.d(\"TAG\", \"THEME: $pathWord\")\n    }\n    fun toMangaSortBean() = MangaSortBean(\n        /* pathName = */ name,\n        /* pathWord = */ pathWord\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicalllist/Results.kt",
    "content": "package com.shicheeng.copymanga.data.topicalllist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<TopicAllListItem>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicalllist/Series.kt",
    "content": "package com.shicheeng.copymanga.data.topicalllist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Series(\n    @Json(name = \"color\")\n    val color: String,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicalllist/TopicAllListDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.topicalllist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class TopicAllListDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicalllist/TopicAllListItem.kt",
    "content": "package com.shicheeng.copymanga.data.topicalllist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class TopicAllListItem(\n    @Json(name = \"brief\")\n    val brief: String,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_created\")\n    val datetimeCreated: String,\n    @Json(name = \"journal\")\n    val journal: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"period\")\n    val period: String,\n    @Json(name = \"series\")\n    val series: Series,\n    @Json(name = \"title\")\n    val title: String,\n    @Json(name = \"type\")\n    val type: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicinfo/Last.kt",
    "content": "package com.shicheeng.copymanga.data.topicinfo\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Last(\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"title\")\n    val title: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicinfo/Results.kt",
    "content": "package com.shicheeng.copymanga.data.topicinfo\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"brief\")\n    val brief: String,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_created\")\n    val datetimeCreated: String,\n    @Json(name = \"intro\")\n    val intro: String,\n    @Json(name = \"journal\")\n    val journal: String,\n    @Json(name = \"last\")\n    val last: Last,\n    @Json(name = \"path\")\n    val path: Any?,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"period\")\n    val period: String,\n    @Json(name = \"series\")\n    val series: Series,\n    @Json(name = \"title\")\n    val title: String,\n    @Json(name = \"type\")\n    val type: Int,\n    @Json(name = \"version\")\n    val version: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicinfo/Series.kt",
    "content": "package com.shicheeng.copymanga.data.topicinfo\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Series(\n    @Json(name = \"color\")\n    val color: String,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topicinfo/TopicInfoDataModelX.kt",
    "content": "package com.shicheeng.copymanga.data.topicinfo\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class TopicInfoDataModelX(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topiclist/Author.kt",
    "content": "package com.shicheeng.copymanga.data.topiclist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topiclist/Results.kt",
    "content": "package com.shicheeng.copymanga.data.topiclist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<TopicItem>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topiclist/Theme.kt",
    "content": "package com.shicheeng.copymanga.data.topiclist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Theme(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topiclist/TopicItem.kt",
    "content": "package com.shicheeng.copymanga.data.topiclist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class TopicItem(\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"c_type\")\n    val cType: Int,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"img_type\")\n    val imgType: Int,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"parodies\")\n    val parodies: List<Any>,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"theme\")\n    val theme: List<Theme>,\n    @Json(name = \"type\")\n    val type: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/topiclist/TopicListDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.topiclist\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class TopicListDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webbookshelf/Author.kt",
    "content": "package com.shicheeng.copymanga.data.webbookshelf\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webbookshelf/Browse.kt",
    "content": "package com.shicheeng.copymanga.data.webbookshelf\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Browse(\n    @Json(name = \"chapter_name\")\n    val chapterName: String,\n    @Json(name = \"chapter_uuid\")\n    val chapterUuid: String,\n    @Json(name = \"comic_uuid\")\n    val comicUuid: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webbookshelf/Comic.kt",
    "content": "package com.shicheeng.copymanga.data.webbookshelf\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Comic(\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"b_display\")\n    val bDisplay: Boolean,\n    @Json(name = \"browse\")\n    val browse: Browse?,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_updated\")\n    val datetimeUpdated: String,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"last_chapter_id\")\n    val lastChapterId: String,\n    @Json(name = \"last_chapter_name\")\n    val lastChapterName: String,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"status\")\n    val status: Int,\n    @Json(name = \"theme\")\n    val theme: List<Any>,\n    @Json(name = \"uuid\")\n    val uuid: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webbookshelf/LastBrowse.kt",
    "content": "package com.shicheeng.copymanga.data.webbookshelf\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class LastBrowse(\n    @Json(name = \"last_browse_id\")\n    val lastBrowseId: String,\n    @Json(name = \"last_browse_name\")\n    val lastBrowseName: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webbookshelf/Results.kt",
    "content": "package com.shicheeng.copymanga.data.webbookshelf\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<WebBookshelfItem>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webbookshelf/WebBookshelf.kt",
    "content": "package com.shicheeng.copymanga.data.webbookshelf\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class WebBookshelf(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webbookshelf/WebBookshelfItem.kt",
    "content": "package com.shicheeng.copymanga.data.webbookshelf\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class WebBookshelfItem(\n    @Json(name = \"b_folder\")\n    val bFolder: Boolean,\n    @Json(name = \"comic\")\n    val comic: Comic,\n    @Json(name = \"folder_id\")\n    val folderId: Any?,\n    @Json(name = \"last_browse\")\n    val lastBrowse: LastBrowse?,\n    @Json(name = \"name\")\n    val name: Any?,\n    @Json(name = \"uuid\")\n    val uuid: Int\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webcomichistory/Browse.kt",
    "content": "package com.shicheeng.copymanga.data.webcomichistory\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Browse(\n    @Json(name = \"chapter_id\")\n    val chapterId: String,\n    @Json(name = \"chapter_name\")\n    val chapterName: String,\n    @Json(name = \"chapter_uuid\")\n    val chapterUuid: String,\n    @Json(name = \"comic_id\")\n    val comicId: String,\n    @Json(name = \"comic_uuid\")\n    val comicUuid: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webcomichistory/Results.kt",
    "content": "package com.shicheeng.copymanga.data.webcomichistory\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"browse\")\n    val browse: Browse?,\n    @Json(name = \"collect\")\n    val collect: Int?,\n    @Json(name = \"is_lock\")\n    val isLock: Boolean,\n    @Json(name = \"is_login\")\n    val isLogin: Boolean,\n    @Json(name = \"is_mobile_bind\")\n    val isMobileBind: Boolean,\n    @Json(name = \"is_vip\")\n    val isVip: Boolean,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webcomichistory/WebComicHistory.kt",
    "content": "package com.shicheeng.copymanga.data.webcomichistory\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\nimport com.shicheeng.copymanga.data.local.LocalChapter\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class WebComicHistory(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webhistory/Author.kt",
    "content": "package com.shicheeng.copymanga.data.webhistory\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Author(\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webhistory/Comic.kt",
    "content": "package com.shicheeng.copymanga.data.webhistory\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Comic(\n    @Json(name = \"author\")\n    val author: List<Author>,\n    @Json(name = \"b_display\")\n    val bDisplay: Boolean,\n    @Json(name = \"cover\")\n    val cover: String,\n    @Json(name = \"datetime_updated\")\n    val datetimeUpdated: String,\n    @Json(name = \"females\")\n    val females: List<Any>,\n    @Json(name = \"last_chapter_id\")\n    val lastChapterId: String,\n    @Json(name = \"last_chapter_name\")\n    val lastChapterName: String,\n    @Json(name = \"males\")\n    val males: List<Any>,\n    @Json(name = \"name\")\n    val name: String,\n    @Json(name = \"path_word\")\n    val pathWord: String,\n    @Json(name = \"popular\")\n    val popular: Int,\n    @Json(name = \"status\")\n    val status: Int,\n    @Json(name = \"theme\")\n    val theme: List<Any>,\n    @Json(name = \"uuid\")\n    val uuid: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webhistory/Results.kt",
    "content": "package com.shicheeng.copymanga.data.webhistory\n\n\nimport androidx.annotation.Keep\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class Results(\n    @Json(name = \"limit\")\n    val limit: Int,\n    @Json(name = \"list\")\n    val list: List<WebHistoryItem>,\n    @Json(name = \"offset\")\n    val offset: Int,\n    @Json(name = \"total\")\n    val total: Int,\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webhistory/WebHistoryDataModel.kt",
    "content": "package com.shicheeng.copymanga.data.webhistory\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class WebHistoryDataModel(\n    @Json(name = \"code\")\n    val code: Int,\n    @Json(name = \"message\")\n    val message: String,\n    @Json(name = \"results\")\n    val results: Results\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/data/webhistory/WebHistoryItem.kt",
    "content": "package com.shicheeng.copymanga.data.webhistory\n\n\nimport com.squareup.moshi.Json\nimport com.squareup.moshi.JsonClass\nimport androidx.annotation.Keep\n\n@Keep\n@JsonClass(generateAdapter = true)\ndata class WebHistoryItem(\n    @Json(name = \"comic\")\n    val comic: Comic,\n    @Json(name = \"id\")\n    val id: Int,\n    @Json(name = \"last_chapter_id\")\n    val lastChapterId: String,\n    @Json(name = \"last_chapter_name\")\n    val lastChapterName: String\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/database/MangaHistoryDataBase.kt",
    "content": "package com.shicheeng.copymanga.database\n\nimport androidx.room.Database\nimport androidx.room.RoomDatabase\nimport com.shicheeng.copymanga.dao.MangeLocalHistoryDao\nimport com.shicheeng.copymanga.dao.SearchHistoryDao\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.data.searchhistory.SearchHistory\n\n@Database(\n    entities = [MangaHistoryDataModel::class, LocalChapter::class, SearchHistory::class],\n    version = 6,\n    exportSchema = false\n)\nabstract class MangaHistoryDataBase : RoomDatabase() {\n\n    abstract fun historyDao(): MangeLocalHistoryDao\n\n    abstract fun keyWordDao(): SearchHistoryDao\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/database/MangaLoginDatabase.kt",
    "content": "package com.shicheeng.copymanga.database\n\nimport androidx.room.Database\nimport androidx.room.RoomDatabase\nimport com.shicheeng.copymanga.dao.MangaLoginDao\nimport com.shicheeng.copymanga.data.login.LocalLoginDataModel\n\n@Database(\n    entities = [LocalLoginDataModel::class],\n    version = 2,\n    exportSchema = false\n)\nabstract class MangaLoginDatabase : RoomDatabase() {\n\n    abstract fun loginDao(): MangaLoginDao\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/database/StringToBeanConvert.kt",
    "content": "package com.shicheeng.copymanga.database\n\nimport androidx.room.TypeConverter\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.data.info.Author\n\n\nclass StringToBeanConvert {\n\n    companion object {\n        private const val SPLIT_OUT = \"，\"\n        private const val SPLIT_INNER = \"-\"\n    }\n\n    @TypeConverter\n    fun stringToListBean(string: String): List<MangaSortBean> {\n        return buildList {\n            string.split(SPLIT_OUT).forEach {\n                val inner = it.split(SPLIT_INNER)\n                if (inner.size == 1) {\n                    add(MangaSortBean(inner[0], inner[0]))\n                } else {\n                    add(MangaSortBean(inner[0], inner[1]))\n                }\n            }\n        }\n    }\n\n    @TypeConverter\n    fun listBeanToString(list: List<MangaSortBean>): String {\n        return buildString {\n            list.forEachIndexed { index, sortBean ->\n                append(\"${sortBean.pathName}$SPLIT_INNER${sortBean.pathWord}\")\n                if (index != list.lastIndex) {\n                    append(SPLIT_OUT)\n                }\n            }\n        }\n    }\n\n}\n\nclass AuthorToStringConvert {\n\n    companion object {\n        private const val SPLIT_OUT = \"，\"\n        private const val SPLIT_INNER = \"-\"\n    }\n\n    @TypeConverter\n    fun stringToListBean(string: String): List<Author> {\n        return buildList {\n            string.split(SPLIT_OUT).forEach {\n                val inner = it.split(SPLIT_INNER)\n                if (inner.size == 1) {\n                    add(Author(inner[0], inner[0]))\n                } else {\n                    add(Author(inner[0], inner[1]))\n                }\n            }\n        }\n    }\n\n    @TypeConverter\n    fun listBeanToString(list: List<Author>): String {\n        return buildString {\n            list.forEachIndexed { index, sortBean ->\n                append(\"${sortBean.name}$SPLIT_INNER${sortBean.pathWord}\")\n                if (index != list.lastIndex) {\n                    append(SPLIT_OUT)\n                }\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/dialog/ConfigPagerSheet.kt",
    "content": "package com.shicheeng.copymanga.dialog\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.FragmentManager\nimport com.google.android.material.bottomsheet.BottomSheetDialogFragment\nimport com.google.android.material.button.MaterialButtonToggleGroup\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.databinding.SheetMangaModelSwitcherBinding\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\n\nclass ConfigPagerSheet : BottomSheetDialogFragment(),\n    MaterialButtonToggleGroup.OnButtonCheckedListener {\n\n    private var _binding: SheetMangaModelSwitcherBinding? = null\n    private val binding get() = _binding!!\n    private lateinit var mode: ReaderMode\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        mode = arguments?.getInt(MODE_BUNDLE)?.let {\n            ReaderMode.idOf(it)\n        } ?: ReaderMode.NORMAL\n    }\n\n    override fun onCreateView(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n        savedInstanceState: Bundle?,\n    ): View {\n        _binding = SheetMangaModelSwitcherBinding.inflate(inflater, container, false)\n        return binding.root\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        binding.readerSwitcherToHorizontal.isChecked = mode == ReaderMode.WEBTOON\n        binding.readerSwitcherToVert.isChecked = mode == ReaderMode.NORMAL\n        binding.readerSwitcherToLToR.isChecked = mode == ReaderMode.STANDARD\n\n\n        binding.readerSwitchersGroup.addOnButtonCheckedListener(this)\n        super.onViewCreated(view, savedInstanceState)\n    }\n\n    override fun onButtonChecked(\n        group: MaterialButtonToggleGroup?,\n        checkedId: Int,\n        isChecked: Boolean,\n    ) {\n        if (!isChecked) {\n            return\n        }\n        val newMode = when (checkedId) {\n            R.id.reader_switcher_to_vert -> ReaderMode.NORMAL\n            R.id.reader_switcher_to_horizontal -> ReaderMode.WEBTOON\n            R.id.reader_switcher_to_l_to_r -> ReaderMode.STANDARD\n            else -> return\n        }\n        if (newMode == mode) {\n            return\n        }\n        findCallBackSetMode()?.onModeChange(newMode) ?: return\n        mode = newMode\n    }\n\n    private fun findCallBackSetMode(): CallBack? {\n        return (parentFragment as? CallBack) ?: (activity as? CallBack)\n    }\n\n    override fun onDestroyView() {\n        _binding = null\n        super.onDestroyView()\n    }\n\n\n    interface CallBack {\n        fun onModeChange(mode: ReaderMode)\n    }\n\n    companion object {\n        private const val TAG = \"TAG_CONFIG_PAGER\"\n        private const val MODE_BUNDLE = \"bundle_reader_mode\"\n\n        fun show(fragmentManager: FragmentManager, reader: ReaderMode) {\n            val args = Bundle()\n            args.putInt(MODE_BUNDLE, reader.id)\n            val fragment = ConfigPagerSheet()\n            fragment.arguments = args\n            return fragment.show(fragmentManager, TAG)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/dialog/ListPreferenceXTheme.kt",
    "content": "package com.shicheeng.copymanga.dialog\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport androidx.preference.ListPreference\n\nclass ListPreferenceXTheme @JvmOverloads constructor(\n    context: Context,\n    attr: AttributeSet? = null,\n    defStyleAttr: Int = androidx.preference.R.attr.dialogPreferenceStyle,\n    defStyleRes: Int = 0,\n) :ListPreference(context,attr,defStyleAttr, defStyleRes){\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/domin/CopyMangaApi.kt",
    "content": "package com.shicheeng.copymanga.domin\n\nimport androidx.annotation.Keep\nimport com.shicheeng.copymanga.data.authormanga.AuthorsMangaDataModel\nimport com.shicheeng.copymanga.data.chapter.ChapterDataModel\nimport com.shicheeng.copymanga.data.commentpush.CommentPushDataModel\nimport com.shicheeng.copymanga.data.finished.FinishedMangaDataModel\nimport com.shicheeng.copymanga.data.info.MangaInfoDataModel\nimport com.shicheeng.copymanga.data.lofininfo.LoginInfoDataModel\nimport com.shicheeng.copymanga.data.login.LoginDataModel\nimport com.shicheeng.copymanga.data.logininfoshort.LoginInfoShortDataModel\nimport com.shicheeng.copymanga.data.mangacomment.MangaCommentDataModel\nimport com.shicheeng.copymanga.data.mangacontent.MangaContentDataModel\nimport com.shicheeng.copymanga.data.newsest.NewestListDataModel\nimport com.shicheeng.copymanga.data.rank.RankDataModel\nimport com.shicheeng.copymanga.data.recommend.RecommendDataModel\nimport com.shicheeng.copymanga.data.search.SearchDataModel\nimport com.shicheeng.copymanga.data.topicalllist.TopicAllListDataModel\nimport com.shicheeng.copymanga.data.topicinfo.TopicInfoDataModelX\nimport com.shicheeng.copymanga.data.topiclist.TopicListDataModel\nimport com.shicheeng.copymanga.data.webbookshelf.WebBookshelf\nimport com.shicheeng.copymanga.data.webcomichistory.WebComicHistory\nimport com.shicheeng.copymanga.data.webhistory.WebHistoryDataModel\nimport retrofit2.http.Field\nimport retrofit2.http.FormUrlEncoded\nimport retrofit2.http.GET\nimport retrofit2.http.POST\nimport retrofit2.http.Path\nimport retrofit2.http.Query\n\n@Keep\ninterface CopyMangaApi {\n\n    @GET(\"/api/v3/ranks\")\n    suspend fun getRank(\n        @Query(\"limit\")\n        limit: Int = 21,\n        @Query(\"offset\")\n        offset: Int,\n        @Query(\"date_type\")\n        dateType: String,\n    ): RankDataModel\n\n    @GET(\"/api/v3/comic2/{path_word}\")\n    suspend fun getMangaInfo(\n        @Path(\"path_word\") pathWord: String,\n        @Query(\"platform\") platform: Int = 3,\n        @Query(\"format\") format: String = \"json\",\n    ): MangaInfoDataModel\n\n    @GET(\"/api/v3/recs\")\n    suspend fun getMangaRecommend(\n        @Query(\"pos\") pos: Int = 3200102,\n        @Query(\"limit\") limit: Int = 21,\n        @Query(\"offset\") offset: Int,\n    ): RecommendDataModel\n\n    @GET(\"/api/v3/update/newest\")\n    suspend fun getMangaNewest(\n        @Query(\"limit\") limit: Int = 21,\n        @Query(\"offset\") offset: Int,\n    ): NewestListDataModel\n\n    @GET(\"/api/v3/comics\")\n    suspend fun fetchMangaFilter(\n        @Query(\"free_type\") freeType: Int = 1,\n        @Query(\"limit\") limit: Int = 21,\n        @Query(\"offset\") offset: Int,\n        @Query(\"top\") top: String? = null,\n        @Query(\"theme\") theme: String? = null,\n        @Query(\"ordering\", encoded = true) ordering: String? = null,\n        @Query(\"_update\") update: Boolean = true,\n    ): FinishedMangaDataModel\n\n    @GET(\"/api/v3/comic/{path_word}/group/default/chapters\")\n    suspend fun fetchChapters(\n        @Path(\"path_word\") pathWord: String,\n        @Query(\"limit\") limit: Int = 500,\n        @Query(\"offset\") offset: Int = 0,\n        @Query(\"platform\") platform: Int = 1,\n    ): ChapterDataModel\n\n    @GET(\"/api/v3/search/comic\")\n    suspend fun search(\n        @Query(\"format\") format: String = \"json\",\n        @Query(\"limit\") limit: Int = 21,\n        @Query(\"offset\") offset: Int,\n        @Query(\"platform\") platform: Int = 1,\n        @Query(\"q\") q: String,\n    ): SearchDataModel\n\n    @GET(\"/api/v3/comic/{path_word}/chapter2/{uuid}\")\n    suspend fun fetchMangaContentPicture(\n        @Path(\"path_word\") pathWord: String,\n        @Path(\"uuid\") uuid: String,\n        @Query(\"platform\") platform: Int = 1,\n    ): MangaContentDataModel\n\n    @GET(\"/api/v3/topic/{name}\")\n    suspend fun getMangaTopicInfo(\n        @Path(\"name\") name: String,\n        @Query(\"platform\") platform: Int = 1,\n    ): TopicInfoDataModelX\n\n    @GET(\"/api/v3/topic/{name}/contents\")\n    suspend fun getMangaTopicList(\n        @Path(\"name\") name: String,\n        @Query(\"type\") type: Int,\n        @Query(\"limit\") limit: Int = 21,\n        @Query(\"offset\") offset: Int,\n        @Query(\"platform\") platform: Int = 1,\n    ): TopicListDataModel\n\n    @GET(\"/api/v3/topics\")\n    suspend fun fetchAllTopicListItem(\n        @Query(\"type\") type: Int = 1,\n        @Query(\"limit\") limit: Int = 21,\n        @Query(\"offset\") offset: Int,\n        @Query(\"_update\") update: Boolean = true,\n    ): TopicAllListDataModel\n\n    @POST(\"/api/v3/login\")\n    @FormUrlEncoded\n    suspend fun login(\n        @Field(\"username\") username: String,\n        @Field(\"password\") passwordB64: String,\n        @Field(\"salt\") salt: Int,\n        @Field(\"source\") source: String = \"freeSite\",\n        @Field(\"version\") version: String = \"2023.08.14\",\n        @Field(\"platform\") platform: Int = 1,\n    ): LoginDataModel\n\n    @GET(\"/api/v3/member/browse/comics\")\n    suspend fun browsedComics(\n        @Query(\"free_type\") freeType: Int = 1,\n        @Query(\"offset\") offset: Int,\n        @Query(\"limit\") limit: Int = 20,\n        @Query(\"_update\") update: Boolean = true,\n    ): WebHistoryDataModel\n\n    @GET(\"/api/v3/member/collect/comics\")\n    suspend fun bookshelfWeb(\n        @Query(\"free_type\") freeType: Int = 1,\n        @Query(\"limit\") limit: Int = 21,\n        @Query(\"offset\") offset: Int,\n        @Query(\"_update\") update: Boolean = true,\n        @Query(\"ordering\") ordering: String = \"-datetime_modifier\",\n    ): WebBookshelf\n\n\n    @GET(\"/api/v3/member/update/info\")\n    suspend fun shortInfo(\n        @Query(\"nickname\") nickname: String = \"\",\n        @Query(\"avatar\") avatar: String = \"\",\n        @Query(\"gender\") gender: String = \"\",\n        @Query(\"birthday\") birthday: String = \"\",\n    ): LoginInfoShortDataModel\n\n    @GET(\"/api/v3/comic2/{word}/query\")\n    suspend fun comicWebHistory(\n        @Path(\"word\") word: String,\n        @Query(\"platform\") platform: Int = 1,\n        @Query(\"_update\") update: Boolean = true,\n    ): WebComicHistory\n\n    @GET(\"/api/v3/comics\")\n    suspend fun comicAuthors(\n        @Query(\"free_type\") freeType: Int = 1,\n        @Query(\"author\") author: String,\n        @Query(\"limit\") limit: Int = 100,\n        @Query(\"offset\") offset: Int,\n        @Query(\"ordering\") ordering: String = \"-datetime_updated\",\n    ): AuthorsMangaDataModel\n\n    @GET(\"/api/v3/comments\")\n    suspend fun comicComments(\n        @Query(\"comic_id\") comicID: String,\n        @Query(\"limit\") limit: Int = 20,\n        @Query(\"offset\") offset: Int,\n    ): MangaCommentDataModel\n\n    @GET(\"/api/v3/member/info\")\n    suspend fun loginInfo(): LoginInfoDataModel\n\n    @FormUrlEncoded\n    @POST(\"/api/v3/member/collect/comic\")\n    suspend fun comicCollect(\n        @Field(\"comic_id\") comicID: String,\n        @Field(\"is_collect\") isCollect: Int,\n        @Field(\"_update\") update: Boolean = true,\n    )\n\n    @FormUrlEncoded\n    @POST(\"/api/v3/member/comment\")\n    suspend fun commentPush(\n        @Field(\"comic_id\") comicId: String,\n        @Field(\"comment\") comment: String,\n        @Field(\"reply_id\") replyId: String = \"\",\n    ): CommentPushDataModel\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/domin/DownloadFileDetectUtil.kt",
    "content": "package com.shicheeng.copymanga.domin\n\nimport android.content.Context\nimport android.os.Environment\nimport androidx.core.net.toUri\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.PersonalInnerDataModel\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport com.shicheeng.copymanga.util.KeyWordSwap\nimport com.shicheeng.copymanga.util.asStringOrNull\nimport com.shicheeng.copymanga.util.getOrNull\nimport com.shicheeng.copymanga.util.nullWillBe\nimport com.shicheeng.copymanga.util.parserAsJson\nimport com.shicheeng.copymanga.util.transformToJsonObjectSafety\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.emptyFlow\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.flow.flowOf\nimport kotlinx.coroutines.runInterruptible\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.io.FileFilter\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass DownloadFileDetectUtil @Inject constructor(\n    @ApplicationContext private val context: Context,\n    private val mangaHistoryRepository: MangaHistoryRepository,\n) {\n\n    private val fileRootPath by lazy {\n        File(\"${context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)}/${KeyWordSwap.SAVED_LOCAL_CHAPTER_NAME}\")\n    }\n\n    private val fileRootPathV2 by lazy {\n        context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)\n    }\n\n    private val allDownloadFiles by lazy { fileRootPathV2?.walk() }\n\n    /**\n     * 获取下载的地址，一般是下载主文件夹名字和漫画名字\n     * @param localSavableMangaModel 本地保存的漫画信息数据模型\n     */\n    fun getRootFile(localSavableMangaModel: LocalSavableMangaModel): File {\n        return File(\n            context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS),\n            \"/${localSavableMangaModel.mangaHistoryDataModel.name}\"\n        )\n    }\n\n    /**\n     * 通过[uuid]检测漫画章节是否下载。\n     * @param pathWord 空安全的漫画PathWord。\n     * @param uuid 空安全的漫画章节uuid。\n     */\n    // TODO: 章节检测不再使用本地暴力检测\n    suspend fun detectChapterDownloadedByUUID(\n        pathWord: String?,\n        uuid: String?,\n    ): Boolean = runInterruptible(Dispatchers.IO) {\n        if (!fileRootPath.exists()) {\n            return@runInterruptible false\n        }\n        val json = fileRootPath.readText().parserAsJson().asJsonArray.find { x ->\n            x.asJsonObject[\"path_word\"].asString == pathWord\n        }?.asJsonObject\n        if (json != null) {\n            json.get(\"manga_downloaded\")\n                ?.asJsonArray\n                ?.find { x -> x.asJsonObject[\"uuid\"].asString == uuid }\n                ?.isJsonNull == false\n        } else {\n            val jsonV2 = allDownloadFiles\n                ?.filter { it.extension == \"json\" }\n                ?.find {\n                    it.readText().parserAsJson().transformToJsonObjectSafety()\n                        ?.get(\"path_word\")?.asString == pathWord\n                }?.readText()?.parserAsJson()?.asJsonObject\n            val chapterInJson = if (jsonV2?.has(\"chapters\") == true) {\n                jsonV2.get(\"chapters\")?.asJsonObject\n            } else null\n            chapterInJson?.has(uuid) == true\n        }\n    }\n\n    suspend fun detectMangaDownloadWithName(\n        name: String,\n        pathWord: String?,\n        uuid: String,\n    ): Boolean = withContext(Dispatchers.IO) {\n        if (!fileRootPath.exists()) {\n            return@withContext false\n        }\n        val json = fileRootPath.readText().parserAsJson().asJsonArray.find { x ->\n            x.asJsonObject[\"path_word\"].asString == pathWord\n        }?.asJsonObject\n        if (json != null) {\n            json.get(\"manga_downloaded\")\n                ?.asJsonArray\n                ?.find { x -> x.asJsonObject[\"uuid\"].asString == uuid }\n                ?.isJsonNull == false\n        } else {\n            val mangaPath = File(fileRootPathV2, \"/$name/${KeyWordSwap.LOCAL_SAVABLE_INDEX_JSON}\")\n            if (!mangaPath.exists()) {\n                return@withContext false\n            } else {\n                val jsonMangaIndex =\n                    mangaPath.readText().parserAsJson().transformToJsonObjectSafety()\n                return@withContext jsonMangaIndex?.has(uuid) == true\n            }\n        }\n    }\n\n    suspend fun detectMangaDownloadWithChapterName(\n        name: String,\n        pathWord: String?,\n        uuid: String,\n    ): Boolean = withContext(Dispatchers.IO) {\n        if (!fileRootPath.exists()) {\n            return@withContext false\n        }\n        val json = fileRootPath.readText().parserAsJson().asJsonArray.find { x ->\n            x.asJsonObject[\"path_word\"].asString == pathWord\n        }?.asJsonObject\n        if (json != null) {\n            json.get(\"manga_downloaded\")\n                ?.asJsonArray\n                ?.find { x -> x.asJsonObject[\"uuid\"].asString == uuid }\n                ?.isJsonNull == false\n        } else {\n            val mangaPath = File(fileRootPathV2, \"/$name/${KeyWordSwap.LOCAL_SAVABLE_INDEX_JSON}\")\n            if (!mangaPath.exists()) {\n                return@withContext false\n            } else {\n                val jsonMangaIndex =\n                    mangaPath.readText().parserAsJson().transformToJsonObjectSafety()\n                return@withContext jsonMangaIndex?.has(uuid) == true\n            }\n        }\n    }\n\n    /**\n     * 找出下载过章节的漫画：通过读取[fileRootPath]和[fileRootPathV2]的文件。\n     */\n    fun findDownloadManga() = flow {\n        val files = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)\n            ?.listFiles()\n        if (files == null) {\n            emit(emptyList())\n            return@flow\n        }\n        val list = files\n            .filter { it.isDirectory }\n            .map { file ->\n                val indexJson = File(\"${file.path}/${KeyWordSwap.LOCAL_SAVABLE_INDEX_JSON}\").takeIf {\n                    it.canRead()\n                }?.readText()?.parserAsJson()?.transformToJsonObjectSafety()\n                val coverPath = indexJson?.getOrNull(\"cover_entry\")?.asString.nullWillBe {\n                    \"cover.png\"\n                }\n                PersonalInnerDataModel(\n                    name = file.name,\n                    url = (\"${file.path}/$coverPath\").toUri(),\n                    pathWord = findChapterPathWordWithName(file.name)\n                        ?: indexJson?.getOrNull(\"path_word\")?.asStringOrNull\n                )\n            }\n        emit(list)\n    }\n\n\n    /**\n     * 通过读取文件来获取漫画的pathWord。\n     * @param name 既是漫画名字也是文件夹的名字。\n     */\n    private fun findChapterPathWordWithName(name: String): String? {\n        if (!fileRootPath.exists()) {\n            return null\n        }\n        val json = fileRootPath.readText().parserAsJson().asJsonArray.find { x ->\n            x.asJsonObject[\"name\"].asString == name\n        }?.asJsonObject\n        return json?.get(\"path_word\")?.asString\n    }\n\n    suspend fun isChapterDownloadedWithStringList(\n        pathWord: String?,\n        uuid: String?,\n    ): Boolean = runInterruptible(Dispatchers.IO) {\n        if (!fileRootPath.exists()) {\n            return@runInterruptible false\n        }\n        val json = fileRootPath.readText().parserAsJson().asJsonArray.find { x ->\n            x.asJsonObject[\"path_word\"].asString == pathWord\n        }?.asJsonObject\n        val jsonNewVersion = fileRootPathV2?.walk()?.filter {\n            it.extension == \"json\"\n        }?.find { x ->\n            x.readText()\n                .parserAsJson()\n                .transformToJsonObjectSafety()?.get(\"path_word\")?.asString == pathWord\n        }?.readText()?.parserAsJson()\n            ?.asJsonObject?.let {\n                if (it.has(\"chapters\")) it.get(\"chapters\").asJsonObject else null\n            }\n        json?.get(\"manga_downloaded\")\n            ?.asJsonArray?.find { x -> x.asJsonObject[\"uuid\"].asString == uuid }\n            ?.isJsonNull == false || jsonNewVersion?.has(uuid) == true\n    }\n\n    //TODO : 完美的漫画本地检测\n    suspend fun ifChapterDownloaded(\n        pathWord: String,\n        uuid: String?,\n    ): List<MangaReaderPage>? = runInterruptible(Dispatchers.IO) {\n        if (!fileRootPath.exists() || fileRootPathV2?.exists() == false) {\n            return@runInterruptible null\n        }\n        val json = File(fileRootPath, KeyWordSwap.SAVED_LOCAL_CHAPTER_NAME)\n            .takeIf { it.exists() }\n            ?.readText()\n            ?.parserAsJson()\n            ?.asJsonArray?.find { x ->\n                x.asJsonObject[\"path_word\"].asString == pathWord\n            }?.asJsonObject\n        if (json != null) {\n            val mangaName = json[\"name\"]?.asString\n            val chapterName = json[\"manga_downloaded\"]?.asJsonArray?.find { x ->\n                x.asJsonObject[\"uuid\"].asString == uuid\n            }?.asJsonObject?.get(\"chapter_name\")?.asString\n            val savePath =\n                \"${context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)}/${mangaName}/${chapterName}\"\n            val file = File(savePath)\n            buildList {\n                file.listFiles(chaptersFileFilter)?.forEachIndexed { index, file ->\n                    add(MangaReaderPage(file.path, uuid, index))\n                }\n            }\n        } else {\n            val jsonInner = allDownloadFiles\n                ?.filter { it.extension == \"json\" }\n                ?.find {\n                    it.readText().parserAsJson().transformToJsonObjectSafety()\n                        ?.get(\"path_word\")?.asString == pathWord\n                }?.readText()?.parserAsJson()?.asJsonObject ?: return@runInterruptible null\n            if (!jsonInner.has(\"chapters\") && !jsonInner.get(\"chapters\").asJsonObject.has(uuid)) {\n                return@runInterruptible null\n            } else {\n                val mangaName = jsonInner.get(\"name\").asString\n                val chapterName = jsonInner\n                    .get(\"chapters\").asJsonObject\n                    .get(uuid).asJsonObject[\"chapter_name\"].asString\n                val file = File(fileRootPathV2, \"${mangaName}/$chapterName\")\n                buildList {\n                    file.listFiles(chaptersFileFilter)?.forEachIndexed { index, fileInner ->\n                        add(MangaReaderPage(fileInner.path, uuid, index))\n                    }\n                }\n            }\n\n        }\n\n    }\n\n    private val chaptersFileFilter = FileFilter {\n        it.extension == \"jpg\"\n                || it.extension == \"webp\"\n                || it.extension == \"jpg\"\n                || it.extension == \"jpeg\"\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/error/ContinuationCallCallback.kt",
    "content": "package com.shicheeng.copymanga.error\n\nimport kotlinx.coroutines.CancellableContinuation\nimport kotlinx.coroutines.CompletionHandler\nimport okhttp3.Call\nimport okhttp3.Callback\nimport okhttp3.Response\nimport java.io.IOException\nimport kotlin.coroutines.Continuation\nimport kotlin.coroutines.resumeWithException\n\nclass ContinuationCallCallback(\n    private val call: Call,\n    private val cancellation: CancellableContinuation<Response>,\n) : Callback, CompletionHandler {\n\n    override fun onFailure(call: Call, e: IOException) {\n        if (!call.isCanceled() && cancellation.isActive) {\n            cancellation.resumeWithException(e)\n        }\n    }\n\n    override fun onResponse(call: Call, response: Response) {\n        if (cancellation.isActive) {\n            cancellation.resume(response)\n        }\n    }\n\n    override fun invoke(cause: Throwable?) {\n        runCatching {\n            call.cancel()\n        }.onFailure {\n            cause?.addSuppressed(it)\n        }\n    }\n}\n\nfun <T> Continuation<T>.resume(value: T): Unit =\n    resumeWith(Result.success(value))"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/error/DownloadErrorException.kt",
    "content": "package com.shicheeng.copymanga.error\n\nclass DownloadErrorException(\n    val comicPathWord: String,\n    val chapterUUID: String,\n) : Exception(\"下载错误\")"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/error/EmptyJsonArray.kt",
    "content": "package com.shicheeng.copymanga.error\n\nclass EmptyJsonArray:Exception() {\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/error/ErrorActivity.kt",
    "content": "package com.shicheeng.copymanga.error\n\nimport android.content.Context\nimport android.content.Intent\nimport android.os.Bundle\nimport androidx.activity.compose.setContent\nimport androidx.core.view.WindowCompat\nimport com.shicheeng.copymanga.app.AppAttachCompatActivity\nimport com.shicheeng.copymanga.ui.screen.error.ErrorScreen\nimport com.shicheeng.copymanga.ui.theme.CopyMangaTheme\n\nclass ErrorActivity : AppAttachCompatActivity() {\n\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        WindowCompat.setDecorFitsSystemWindows(window, false)\n        val message = intent?.getStringExtra(ERROR_MESSAGE)\n        setContent {\n            CopyMangaTheme {\n                ErrorScreen(message = message) {\n                    finish()\n                }\n            }\n        }\n    }\n\n    companion object {\n        fun newIntentInstance(\n            context: Context,\n            errorMessage: String?,\n        ): Intent {\n            val intent = Intent(context, ErrorActivity::class.java)\n            intent.putExtra(ERROR_MESSAGE, errorMessage)\n            return intent\n        }\n\n        private const val ERROR_MESSAGE = \"ERROR_MESSAGE\"\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/delegate/IdlingDelegate.kt",
    "content": "package com.shicheeng.copymanga.fm.delegate\n\nimport android.os.Handler\nimport android.os.Looper\nimport androidx.lifecycle.DefaultLifecycleObserver\nimport androidx.lifecycle.LifecycleOwner\nimport java.util.concurrent.TimeUnit\n\n/**\n * 大部分代码来自Kotatsu。\n */\nclass IdlingDelegate(private val idleCallback: IdleCallback) : DefaultLifecycleObserver {\n\n\n    private val handler = Handler(Looper.getMainLooper())\n    private val idleRunnable = Runnable {\n        idleCallback.onIdle()\n    }\n\n    fun bindToLifecycle(owner: LifecycleOwner) {\n        owner.lifecycle.addObserver(this)\n    }\n\n    fun onUserInteraction() {\n        handler.removeCallbacks(idleRunnable)\n        handler.postDelayed(idleRunnable, TimeUnit.SECONDS.toMillis(10))\n    }\n\n    override fun onDestroy(owner: LifecycleOwner) {\n        super.onDestroy(owner)\n        owner.lifecycle.removeObserver(this)\n        handler.removeCallbacks(idleRunnable)\n    }\n\n    fun interface IdleCallback {\n        fun onIdle()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/domain/ChapterLoader.kt",
    "content": "package com.shicheeng.copymanga.fm.domain\n\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.domin.DownloadFileDetectUtil\nimport com.shicheeng.copymanga.resposity.MangaInfoRepository\nimport dagger.hilt.android.scopes.ViewModelScoped\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport javax.inject.Inject\n\n@ViewModelScoped\nclass ChapterLoader @Inject constructor(\n    private val fileDetectUtil: DownloadFileDetectUtil,\n    private val repository: MangaInfoRepository,\n) {\n\n    val chapters = LinkedHashMap<String, LocalChapter>()\n    val nextChapterLoadingState =\n        MutableStateFlow<NextChapterLoadState>(NextChapterLoadState.NotLoading)\n\n    private val chapterPage = ChapterPages()\n    private val mutex = Mutex()\n\n    suspend fun init(list: List<LocalChapter>?) = mutex.withLock {\n        chapters.clear()\n        list?.forEach {\n            chapters[it.uuid] = it\n        }\n    }\n\n    suspend fun loadPrevNextChapter(\n        list: List<LocalChapter>?,\n        uuid: String?,\n        isNext: Boolean,\n    ) {\n        nextChapterLoadingState.emit(NextChapterLoadState.Loading)\n        val chapters = list ?: return\n        val predicate: (LocalChapter) -> Boolean = { it.uuid == uuid }\n        val index =\n            if (isNext) chapters.indexOfFirst(predicate) else chapters.indexOfLast(predicate)\n        if (index == -1) return\n        val newChapter = chapters.getOrNull(if (isNext) index + 1 else index - 1) ?: return\n        try {\n            val newPages = loadChapter(newChapter.comicPathWord, newChapter.uuid)\n            mutex.withLock {\n                if (chapterPage.chapterSize > 1) {\n                    if (chapterPage.size > 130) {\n                        if (isNext) {\n                            chapterPage.removeFirst()\n                        } else {\n                            chapterPage.removeLast()\n                        }\n                    }\n                }\n                if (isNext) {\n                    chapterPage.addLast(newChapter.uuid, newPages)\n                } else {\n                    chapterPage.addFirst(newChapter.uuid, newPages)\n                }\n                nextChapterLoadingState.emit(NextChapterLoadState.NotLoading)\n            }\n        } catch (e: Exception) {\n            nextChapterLoadingState.emit(NextChapterLoadState.Error(e))\n        }\n\n    }\n\n    suspend fun loadSingleChapter(pathWord: String, uuid: String) {\n        val page = loadChapter(pathWord, uuid)\n        mutex.withLock {\n            chapterPage.clear()\n            chapterPage.addLast(uuid, page)\n        }\n    }\n\n    fun getPage(uuid: String): List<MangaReaderPage> {\n        return chapterPage.subList(uuid)\n    }\n\n    operator fun get(uuid: String): Int {\n        return chapterPage.size(uuid)\n    }\n\n    fun snapshot() = chapterPage.toList()\n\n    fun last() = chapterPage.last()\n\n    fun first() = chapterPage.first()\n\n    val size get() = chapters.size\n\n    private suspend fun loadChapter(pathWord: String, uui: String): List<MangaReaderPage> {\n        val chapter = checkNotNull(chapters[uui]) { \"NO CHAPTER FOUND\" }\n        val isDownload = fileDetectUtil.isChapterDownloadedWithStringList(pathWord, chapter.uuid)\n        val listLocal =\n            if (isDownload) fileDetectUtil.ifChapterDownloaded(pathWord, chapter.uuid) else null\n        return repository.fetchContentMayLocal(listLocal, pathWord, chapter.uuid)\n    }\n\n    sealed class NextChapterLoadState {\n\n        object Loading : NextChapterLoadState()\n        data class Error(val e: Throwable) : NextChapterLoadState()\n        object NotLoading : NextChapterLoadState()\n\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/domain/ChapterPages.kt",
    "content": "package com.shicheeng.copymanga.fm.domain\n\nimport com.shicheeng.copymanga.data.MangaReaderPage\n\n/**\n * Copy from Kotatsu\n *\n * The class was _reformed_ for this App\n */\nclass ChapterPages private constructor(private val pages: ArrayDeque<MangaReaderPage>) :\n    List<MangaReaderPage> by pages {\n\n    private val indices = LinkedHashMap<String, IntRange>()\n\n    constructor() : this(ArrayDeque())\n\n    val chapterSize: Int get() = indices.size\n\n    fun removeFirst() {\n        val chapterId = pages.first().uuid\n        indices.remove(chapterId)\n        var delta = 0\n        while (pages.first().uuid == chapterId) {\n            pages.removeFirst()\n            delta--\n        }\n        shiftIndices(delta)\n    }\n\n    fun removeLast() {\n        val chapterId = pages.last().uuid\n        indices.remove(chapterId)\n        while (pages.last().uuid == chapterId) {\n            pages.removeLast()\n        }\n    }\n\n    fun addLast(id: String, newPages: List<MangaReaderPage>) {\n        indices[id] = pages.size until (pages.size + newPages.size)\n        pages.addAll(newPages)\n    }\n\n    fun addFirst(id: String, newPages: List<MangaReaderPage>) {\n        shiftIndices(newPages.size)\n        indices[id] = newPages.indices\n        pages.addAll(0, newPages)\n    }\n\n    fun clear() {\n        indices.clear()\n        pages.clear()\n    }\n\n    fun size(id: String) = indices[id]?.run {\n        endInclusive - start + 1\n    } ?: 0\n\n    fun subList(id: String): List<MangaReaderPage> {\n        val range = indices[id] ?: return emptyList()\n        return pages.subList(range.first, range.last + 1)\n    }\n\n    private fun shiftIndices(delta: Int) {\n        indices.forEach { (t, u) ->\n            indices[t] = u + delta\n        }\n    }\n\n    private operator fun IntRange.plus(delta: Int): IntRange {\n        return IntRange(start + delta, endInclusive + delta)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/domain/PageHolderDelegate.kt",
    "content": "package com.shicheeng.copymanga.fm.domain\n\nimport android.net.Uri\nimport androidx.core.net.toUri\nimport com.davemorrissey.labs.subscaleview.DefaultOnImageEventListener\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.cancelAndJoin\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.plus\nimport java.io.File\nimport java.io.IOException\n\nclass PageHolderDelegate(\n    private val loader: PagerLoader,\n    private val callback: Callback,\n) : DefaultOnImageEventListener {\n\n    private var job: Job? = null\n    private val scope = loader.loaderScope + Dispatchers.Main.immediate\n    private var state = State.EMPTY\n    private var file: File? = null\n\n    fun onBind(url: String) {\n        val prevJop = job\n        job = scope.launch {\n            prevJop?.cancelAndJoin()\n            doLoad(url, false)\n        }\n    }\n\n    fun retry(url: String) {\n        val prevJob = job\n        job = scope.launch {\n            prevJob?.cancelAndJoin()\n            doLoad(url, true)\n        }\n    }\n\n    fun onRecycler() {\n        state = State.EMPTY\n        file = null\n        job?.cancel()\n    }\n\n    override fun onReady() {\n        super.onReady()\n        state = State.SHOWING\n        callback.onImageShowing()\n    }\n\n    override fun onImageLoaded() {\n        super.onImageLoaded()\n        state = State.SHOWN\n        callback.onImageShown()\n    }\n\n    override fun onImageLoadError(e: Throwable) {\n        val file = this.file\n        if (state == State.LOADED && e is IOException && file != null && file.exists()) {\n            tryConvert(file, e)\n        } else {\n            state = State.ERROR\n            callback.onError(e = e)\n        }\n        callback.onError(e)\n    }\n\n    private suspend fun doLoad(url: String, force: Boolean) {\n        state = State.LOADING\n        callback.onLoadingStarted()\n        try {\n            val task = loader.loadImageFromUrlAsync(url, force)\n            file = coroutineScope {\n                task.await()\n            }\n            state = State.LOADED\n            callback.onImageReady(checkNotNull(file).toUri())\n        } catch (e: Exception) {\n            state = State.ERROR\n            callback.onError(e)\n        }\n\n    }\n\n    private fun tryConvert(file: File, e: Exception) {\n        val prevJob = job\n        job = scope.launch {\n            prevJob?.join()\n            state = State.CONVERTING\n            try {\n                loader.convertInPlace(file)\n                state = State.CONVERTED\n                callback.onImageReady(file.toUri())\n            } catch (ce: CancellationException) {\n                throw ce\n            } catch (e2: Throwable) {\n                e.addSuppressed(e2)\n                state = State.ERROR\n                callback.onError(e = e)\n            }\n        }\n    }\n\n    private enum class State {\n        EMPTY, LOADING, LOADED, CONVERTING, CONVERTED, SHOWING, SHOWN, ERROR\n    }\n\n    interface Callback {\n\n        fun onLoadingStarted()\n\n        fun onError(e: Throwable)\n\n        fun onImageReady(uri: Uri)\n\n        fun onImageShowing()\n\n        fun onImageShown()\n    }\n\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/domain/PagerCache.kt",
    "content": "package com.shicheeng.copymanga.fm.domain\n\nimport android.content.Context\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.tomclaw.cache.DiskLruCache\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.ensureActive\nimport kotlinx.coroutines.withContext\nimport java.io.File\nimport java.io.InputStream\nimport java.io.OutputStream\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass PagerCache @Inject constructor(\n    @ApplicationContext context: Context,\n    settingPref: SettingPref,\n) {\n\n    private val cache = (context.externalCacheDirs + context.cacheDir).firstNotNullOfOrNull {\n        it.makeDirIfNoExist()\n    }.let { file ->\n        checkNotNull(file) {\n            val dirs = (context.externalCacheDirs + context.cacheDir).joinToString(\";\") {\n                it.absolutePath\n            }\n            \"Cannot find directory for PagesCache: [$dirs]\"\n        }\n    }\n\n    private val lruCache = createDiskLruCacheSafe(\n        dir = cache,\n        size = FileSize.MEGABYTES.convert(settingPref.cacheSize.toLong(), FileSize.BYTES),\n    )\n\n    operator fun get(url: String): File? {\n        return lruCache.get(url)?.takeIfReadable()\n    }\n\n    suspend fun put(url: String, inputStream: InputStream): File = withContext(Dispatchers.IO) {\n        val file = File(cache.parentFile, url.longHashCode().toString())\n        try {\n            file.outputStream().use { out ->\n                inputStream.copyToSuspending(out)\n            }\n            lruCache.put(url, file)\n        } finally {\n            file.delete()\n        }\n    }\n\n    private fun createDiskLruCacheSafe(dir: File, size: Long): DiskLruCache {\n        return try {\n            DiskLruCache.create(dir, size)\n        } catch (e: Exception) {\n            dir.deleteRecursively()\n            dir.mkdir()\n            DiskLruCache.create(dir, size)\n        }\n    }\n\n    /**\n     * Copy from kotatsu\n     */\n    private suspend fun InputStream.copyToSuspending(\n        out: OutputStream,\n        bufferSize: Int = DEFAULT_BUFFER_SIZE,\n    ): Long = withContext(Dispatchers.IO) {\n        val job = currentCoroutineContext()[Job]\n        var bytesCopied: Long = 0\n        val buffer = ByteArray(bufferSize)\n        var bytes = read(buffer)\n        while (bytes >= 0) {\n            out.write(buffer, 0, bytes)\n            bytesCopied += bytes\n            job?.ensureActive()\n            bytes = read(buffer)\n            job?.ensureActive()\n        }\n        bytesCopied\n    }\n\n    /**\n     * Come from Kotatsu\n     */\n    private fun String.longHashCode(): Long {\n        var h = 1125899906842597L\n        val len: Int = this.length\n        for (i in 0 until len) {\n            h = 31 * h + this[i].code\n        }\n        return h\n    }\n\n    /**\n     * Come from Kotatsu\n     */\n    private fun File.takeIfReadable() = takeIf { it.exists() && it.canRead() }\n\n}\n\nfun File.makeDirIfNoExist(): File {\n    if (!this.exists()) {\n        if (this.parentFile?.exists() != true) this.parentFile?.mkdir()\n        if (this.parentFile?.canWrite() != true) this.parentFile?.canWrite()\n        this.mkdir()\n    }\n    return this\n}\n\n/**\n *\n * Copy from Kotatsu\n */\nenum class FileSize(private val multiplier: Int) {\n\n    BYTES(1), KILOBYTES(1024), MEGABYTES(1024 * 1024);\n\n    fun convert(amount: Long, target: FileSize): Long = amount * multiplier / target.multiplier\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/domain/PagerLoader.kt",
    "content": "package com.shicheeng.copymanga.fm.domain\n\nimport android.graphics.Bitmap\nimport android.graphics.BitmapFactory\nimport android.net.Uri\nimport androidx.collection.LongSparseArray\nimport androidx.collection.set\nimport com.shicheeng.copymanga.util.RetainedLifecycleCoroutineScope\nimport dagger.hilt.android.ActivityRetainedLifecycle\nimport dagger.hilt.android.lifecycle.RetainedLifecycle\nimport dagger.hilt.android.scopes.ActivityRetainedScoped\nimport kotlinx.coroutines.CompletableDeferred\nimport kotlinx.coroutines.CoroutineExceptionHandler\nimport kotlinx.coroutines.Deferred\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.invoke\nimport kotlinx.coroutines.plus\nimport kotlinx.coroutines.runInterruptible\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport okhttp3.Headers\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport java.io.File\nimport java.io.InputStream\nimport java.util.LinkedList\nimport java.util.concurrent.atomic.AtomicInteger\nimport javax.inject.Inject\nimport kotlin.coroutines.AbstractCoroutineContextElement\nimport kotlin.coroutines.CoroutineContext\n\n@ActivityRetainedScoped\nclass PagerLoader @Inject constructor(\n    lifecycle: ActivityRetainedLifecycle,\n    private val cache: PagerCache,\n    private val headers: Headers,\n    private val okHttpClient: OkHttpClient,\n) : RetainedLifecycle.OnClearedListener {\n\n    val loaderScope =\n        RetainedLifecycleCoroutineScope(lifecycle) + InternalErrorHandler() + Dispatchers.Default\n    private val tasks = LongSparseArray<Deferred<File>>()\n    private val prefetchQueue = LinkedList<String>()\n    private val counter = AtomicInteger(0)\n    private val convertLock = Mutex()\n\n    init {\n        lifecycle.addOnClearedListener(this)\n    }\n\n    private fun onIdle() {\n        synchronized(prefetchQueue) {\n            while (prefetchQueue.isNotEmpty()) {\n                val url = prefetchQueue.pollFirst() ?: return\n                if (cache[url] == null) {\n                    synchronized(tasks) {\n                        tasks[url.hashCode().toLong()] = loadPageAsync(url)\n                    }\n                    return\n                }\n            }\n        }\n    }\n\n    fun loadImageFromUrlAsync(url: String, force: Boolean): Deferred<File> {\n        if (!force) {\n            cache[url]?.let {\n                return getCompletedTaskAsync(it)\n            }\n        }\n        var task = tasks[url.hashCode().toLong()]\n        if (force) {\n            task?.cancel()\n        } else if (task?.isCancelled == false) {\n            return task\n        }\n        task = loadPageAsync(url)\n        synchronized(tasks) {\n            tasks[url.hashCode().toLong()] = task\n        }\n        return task\n    }\n\n    private fun loadPageAsync(url: String): Deferred<File> {\n        val deferred = loaderScope.async {\n            try {\n                loadPagePicBitmap(url)\n            } finally {\n                if (counter.decrementAndGet() == 0) {\n                    onIdle()\n                }\n            }\n        }\n        return deferred\n    }\n\n\n    suspend fun convertInPlace(file: File) {\n        convertLock.withLock {\n            runInterruptible(Dispatchers.Default) {\n                val image = BitmapFactory.decodeFile(file.absolutePath)\n                try {\n                    file.outputStream().use { out ->\n                        image.compress(Bitmap.CompressFormat.PNG, 100, out)\n                    }\n                } finally {\n                    image.recycle()\n                }\n            }\n        }\n    }\n\n    private suspend fun loadPagePicBitmap(url: String): File = Dispatchers.IO {\n        val uri = Uri.parse(url)\n        if (uri.scheme == \"https\") {\n            val request = Request.Builder()\n                .headers(headers).url(url).get()\n                .build()\n            okHttpClient.newCall(request).execute().use { res ->\n                val ins = checkNotNull(res.body).byteStream()\n                cache.put(url, ins)\n            }\n        } else {\n            val input: InputStream = File(url).inputStream()\n            cache.put(url, input)\n        }\n\n    }\n\n    private fun getCompletedTaskAsync(file: File): Deferred<File> {\n        return CompletableDeferred(file)\n    }\n\n    private class InternalErrorHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler),\n        CoroutineExceptionHandler {\n\n        override fun handleException(context: CoroutineContext, exception: Throwable) {\n            exception.printStackTrace()\n        }\n    }\n\n    override fun onCleared() {\n        synchronized(tasks) {\n            tasks.clear()\n        }\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/BaseReader.kt",
    "content": "package com.shicheeng.copymanga.fm.reader\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.activityViewModels\nimport androidx.viewbinding.ViewBinding\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.MangaState\nimport com.shicheeng.copymanga.util.observe\nimport com.shicheeng.copymanga.viewmodel.ReaderViewModel\n\nabstract class BaseReader<VB : ViewBinding> : Fragment() {\n\n    private var _binding: VB? = null\n    protected val viewModel by activityViewModels<ReaderViewModel>()\n    protected val binding: VB get() = checkNotNull(_binding)\n    protected var readerAdapter: BaseReaderAdapter<*>? = null\n\n    override fun onCreateView(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n        savedInstanceState: Bundle?,\n    ): View? {\n        val binding = onCreateViewInflater(inflater, container)\n        _binding = binding\n        return binding.root\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        readerAdapter = createAdapter()\n        viewModel.mangaContent.observe(viewLifecycleOwner) {\n            onLoadUrlChangeSuccess(it.list, it.state)\n        }\n        super.onViewCreated(view, savedInstanceState)\n    }\n\n    override fun onDestroyView() {\n        _binding = null\n        readerAdapter = null\n        super.onDestroyView()\n    }\n\n    protected fun bindingOrNull() = _binding\n\n    protected abstract fun onCreateViewInflater(inflater: LayoutInflater, container: ViewGroup?): VB\n\n    protected abstract suspend fun onLoadUrlChangeSuccess(\n        list: List<MangaReaderPage>,\n        state: MangaState?,\n    )\n\n    protected fun requireBinding() = requireNotNull(_binding) {\n        \"NO BIND VIEW HERE\"\n    }\n\n    protected fun requireAdapter() = checkNotNull(readerAdapter) {\n        \"NO ADAPTER HERE\"\n    }\n\n    protected abstract fun createAdapter(): BaseReaderAdapter<*>\n\n    abstract fun currentState(): MangaState?\n\n    abstract fun moveToPosition(position: Int, smooth: Boolean)\n\n    abstract fun moveDelta(delta: Int)\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/BaseReaderAdapter.kt",
    "content": "package com.shicheeng.copymanga.fm.reader\n\nimport android.view.ViewGroup\nimport androidx.recyclerview.widget.AsyncListDiffer\nimport androidx.recyclerview.widget.DiffUtil\nimport androidx.recyclerview.widget.RecyclerView\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport kotlin.coroutines.resume\nimport kotlin.coroutines.suspendCoroutine\n\n@Suppress(\"LeakingThis\")\nabstract class BaseReaderAdapter<VH : BaseReaderViewHolder<*>> :\n    RecyclerView.Adapter<VH>() {\n\n\n    private val diff = AsyncListDiffer(this, DIffCallBack())\n\n    init {\n        stateRestorationPolicy = StateRestorationPolicy.PREVENT\n    }\n\n    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH =\n        onCreateViewHolder(parent)\n\n    override fun onBindViewHolder(holder: VH, position: Int) {\n        holder.bind(url = diff.currentList[position].url)\n    }\n\n    open fun getItem(position: Int): MangaReaderPage = diff.currentList[position]\n\n    open fun getItemOrNull(position: Int): MangaReaderPage? = diff.currentList.getOrNull(position)\n\n    override fun getItemCount(): Int = diff.currentList.size\n\n    suspend fun subItems(list: List<MangaReaderPage>) = suspendCoroutine { continuation ->\n        diff.submitList(list) {\n            continuation.resume(Unit)\n        }\n    }\n\n    override fun onViewRecycled(holder: VH) {\n        holder.onRecycler()\n        super.onViewRecycled(holder)\n    }\n\n    protected abstract fun onCreateViewHolder(parent: ViewGroup): VH\n\n    private class DIffCallBack : DiffUtil.ItemCallback<MangaReaderPage>() {\n        override fun areItemsTheSame(\n            oldItem: MangaReaderPage,\n            newItem: MangaReaderPage,\n        ): Boolean = oldItem === newItem\n\n        override fun areContentsTheSame(\n            oldItem: MangaReaderPage,\n            newItem: MangaReaderPage,\n        ): Boolean = oldItem == newItem\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/BaseReaderViewHolder.kt",
    "content": "package com.shicheeng.copymanga.fm.reader\n\nimport android.content.Context\nimport androidx.recyclerview.widget.RecyclerView.ViewHolder\nimport androidx.viewbinding.ViewBinding\nimport com.shicheeng.copymanga.databinding.LayoutImageLoadBinding\nimport com.shicheeng.copymanga.fm.domain.PageHolderDelegate\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\n\n@Suppress(\"LeakingThis\")\nabstract class BaseReaderViewHolder<VB : ViewBinding>(\n    protected val binding: VB,\n    imageLoader: PagerLoader,\n) : ViewHolder(binding.root), PageHolderDelegate.Callback {\n\n    val context: Context get() = itemView.context\n    protected val bindingInfo = LayoutImageLoadBinding.bind(binding.root)\n    protected val delegate = PageHolderDelegate(imageLoader, this)\n\n\n    fun bind(url: String) {\n        delegate.onBind(url)\n        onBind(url)\n    }\n\n    open fun onRecycler() {\n        delegate.onRecycler()\n    }\n\n    abstract fun onBind(url: String)\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/MangaLoader.kt",
    "content": "package com.shicheeng.copymanga.fm.reader\n\nimport androidx.lifecycle.SavedStateHandle\n\nclass MangaLoader(\n    savedStateHandle: SavedStateHandle,\n) {\n\n    val mangaPathWord = savedStateHandle.get<String>(MANGA_PATH_WORD) ?: NONE\n    val mangaChapterUUID = savedStateHandle.get<String>(MANGA_UUID) ?: CHAPTER_NONE\n\n    companion object {\n        const val MANGA_PATH_WORD = \"MANGA_PATH_WORD\"\n        const val MANGA_UUID = \"MANGA_UUID\"\n\n        const val NONE = \"NONE\"\n        const val CHAPTER_NONE = \"CHAPTER_NONE\"\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/ReaderManager.kt",
    "content": "package com.shicheeng.copymanga.fm.reader\n\nimport androidx.annotation.IdRes\nimport androidx.fragment.app.FragmentManager\nimport androidx.fragment.app.commit\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.fm.reader.noraml.ReaderPageFragment\nimport com.shicheeng.copymanga.fm.reader.standard.ReaderPagerStandardFragment\nimport com.shicheeng.copymanga.fm.reader.webtoon.WebtoonReaderFragment\nimport java.util.EnumMap\n\nclass ReaderManager(\n    private val supportFragmentManager: FragmentManager,\n    @IdRes private val containerId: Int,\n) {\n\n    private val modeMap = EnumMap<ReaderMode, Class<out BaseReader<*>>>(ReaderMode::class.java)\n\n    init {\n        modeMap[ReaderMode.NORMAL] = ReaderPageFragment::class.java\n        modeMap[ReaderMode.WEBTOON] = WebtoonReaderFragment::class.java\n        modeMap[ReaderMode.STANDARD] = ReaderPagerStandardFragment::class.java\n    }\n\n    val currentReader: BaseReader<*>?\n        get() = supportFragmentManager.findFragmentById(containerId) as? BaseReader<*>\n\n    val currentReaderMode: ReaderMode?\n        get() {\n            val readerClass = currentReader?.javaClass ?: return null\n            return modeMap.entries.find { it.value == readerClass }?.key\n        }\n\n    fun replace(newMode: ReaderMode) {\n        val readerClass = requireNotNull(modeMap[newMode])\n        supportFragmentManager.commit {\n            setReorderingAllowed(true)\n            replace(containerId, readerClass, null, null)\n        }\n    }\n\n    fun replace(reader: BaseReader<*>) {\n        supportFragmentManager.commit {\n            setReorderingAllowed(true)\n            replace(containerId, reader)\n        }\n    }\n\n}\n\nenum class ReaderMode(@IdRes val id: Int) {\n    NORMAL(R.string.japanese_r_to_l),\n    WEBTOON(R.string.korea_chinese_top_to_bottom),\n    STANDARD(R.string.manga_mode_l_t_r);\n\n    companion object {\n        fun idOf(id: Int?) = values().firstOrNull {\n            it.id == id\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/noraml/PageSliderFormatter.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.noraml\n\nimport com.google.android.material.slider.LabelFormatter\n\nclass PageSliderFormatter : LabelFormatter {\n\n    override fun getFormattedValue(value: Float): String {\n        return (value + 1).toInt().toString()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/noraml/ReaderPageAdapter.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.noraml\n\nimport android.view.LayoutInflater\nimport android.view.MotionEvent\nimport android.view.ViewGroup\nimport androidx.lifecycle.LifecycleOwner\nimport com.shicheeng.copymanga.databinding.ItemPageBinding\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.BaseReaderAdapter\n\nclass ReaderPageAdapter(private val owner: LifecycleOwner, private val imageLoader: PagerLoader) :\n    BaseReaderAdapter<ReaderPageViewHolder>() {\n\n\n    override fun onCreateViewHolder(parent: ViewGroup): ReaderPageViewHolder = ReaderPageViewHolder(\n        ItemPageBinding.inflate(LayoutInflater.from(parent.context), parent, false),\n        imageLoader, owner\n    )\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/noraml/ReaderPageFragment.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.noraml\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport com.google.android.material.snackbar.Snackbar\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.MangaState\nimport com.shicheeng.copymanga.databinding.FragmentReaderNormalBinding\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.BaseReader\nimport com.shicheeng.copymanga.fm.reader.BaseReaderAdapter\nimport com.shicheeng.copymanga.util.onPageChangeCallback\nimport dagger.hilt.android.AndroidEntryPoint\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.yield\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nopen class ReaderPageFragment : BaseReader<FragmentReaderNormalBinding>() {\n\n    @Inject\n    lateinit var pagerLoader: PagerLoader\n\n    override fun onCreateViewInflater(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n    ): FragmentReaderNormalBinding = FragmentReaderNormalBinding.inflate(inflater, container, false)\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        binding.mangaReaderViewpager2.layoutDirection = View.LAYOUT_DIRECTION_RTL\n\n        with(binding.mangaReaderViewpager2) {\n            adapter = readerAdapter\n            offscreenPageLimit = 1\n            onPageChangeCallback {\n                viewModel.onPagePositionChange(it)\n            }\n        }\n    }\n\n    override fun onDestroyView() {\n        requireBinding().mangaReaderViewpager2.adapter = null\n        super.onDestroyView()\n    }\n\n    override fun moveToPosition(position: Int, smooth: Boolean) {\n        binding.mangaReaderViewpager2.setCurrentItem(position, smooth)\n    }\n\n    override fun currentState(): MangaState? = bindingOrNull()?.run {\n        val adapter = mangaReaderViewpager2.adapter as? BaseReaderAdapter<*>\n        val page = adapter?.getItemOrNull(mangaReaderViewpager2.currentItem) ?: return@run null\n        MangaState(page.uuid ?: return@run null, page.index)\n    }\n\n    override fun moveDelta(delta: Int) {\n        binding.mangaReaderViewpager2.currentItem =\n            binding.mangaReaderViewpager2.currentItem + delta\n    }\n\n    override suspend fun onLoadUrlChangeSuccess(\n        list: List<MangaReaderPage>,\n        state: MangaState?,\n    ) = coroutineScope {\n        val items = async {\n            requireAdapter().subItems(list)\n            yield()\n        }\n        if (state != null) {\n            val position = list.indexOfFirst {\n                it.uuid == state.uuid && it.index == state.page\n            }\n            items.await()\n            if (position != -1) {\n                binding.mangaReaderViewpager2.setCurrentItem(position, false)\n                viewModel.onPagePositionChange(position)\n            } else {\n                Snackbar.make(requireView(), getString(R.string.no_content), Snackbar.LENGTH_LONG)\n                    .show()\n            }\n        } else {\n            items.await()\n        }\n    }\n\n\n    override fun createAdapter(): BaseReaderAdapter<*> {\n        return ReaderPageAdapter(\n            owner = viewLifecycleOwner,\n            imageLoader = pagerLoader\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/noraml/ReaderPageViewHolder.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.noraml\n\nimport android.annotation.SuppressLint\nimport android.net.Uri\nimport androidx.core.view.isVisible\nimport androidx.lifecycle.LifecycleOwner\nimport com.davemorrissey.labs.subscaleview.ImageSource\nimport com.shicheeng.copymanga.databinding.ItemPageBinding\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.BaseReaderViewHolder\n\n@SuppressLint(\"ClickableViewAccessibility\")\nclass ReaderPageViewHolder(\n    binding: ItemPageBinding,\n    imageLoader: PagerLoader,\n    owner: LifecycleOwner,\n) :\n    BaseReaderViewHolder<ItemPageBinding>(binding, imageLoader) {\n\n    private var url: String? = null\n\n    init {\n        binding.bivPager.bindToLifecycle(owner)\n        binding.bivPager.addOnImageEventListener(delegate)\n    }\n\n    override fun onBind(url: String) {\n        this.url = url\n    }\n\n    override fun onLoadingStarted() {\n        binding.errorLayout.errorTextLayout.isVisible = false\n        bindingInfo.loadIndicator.isVisible = true\n        binding.bivPager.recycle()\n    }\n\n    override fun onError(e: Throwable) {\n        e.printStackTrace()\n        with(binding.errorLayout) {\n            errorTextLayout.isVisible = true\n            errorTextTipDesc.text = e.message\n            btnErrorRetry.setOnClickListener {\n                url?.let { it1 ->\n                    delegate.retry(it1)\n                }\n            }\n        }\n        bindingInfo.loadIndicator.isVisible = false\n    }\n\n    override fun onImageReady(uri: Uri) {\n        binding.bivPager.setImage(ImageSource.Uri(uri))\n    }\n\n    override fun onImageShowing() {\n        binding.bivPager.maxScale = 2f * maxOf(\n            binding.bivPager.width / binding.bivPager.sWidth.toFloat(),\n            binding.bivPager.height / binding.bivPager.sHeight.toFloat(),\n        )\n    }\n\n    override fun onImageShown() {\n        bindingInfo.loadIndicator.isVisible = false\n        binding.errorLayout.errorTextLayout.isVisible = false\n    }\n\n    override fun onRecycler() {\n        super.onRecycler()\n        binding.bivPager.recycle()\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/standard/ReaderPagerStandardFragment.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.standard\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport com.google.android.material.snackbar.Snackbar\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.MangaState\nimport com.shicheeng.copymanga.databinding.FragmentReaderNormalBinding\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.BaseReader\nimport com.shicheeng.copymanga.fm.reader.BaseReaderAdapter\nimport com.shicheeng.copymanga.fm.reader.noraml.ReaderPageAdapter\nimport com.shicheeng.copymanga.util.onPageChangeCallback\nimport dagger.hilt.android.AndroidEntryPoint\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.yield\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nclass ReaderPagerStandardFragment : BaseReader<FragmentReaderNormalBinding>() {\n\n    @Inject\n    lateinit var pagerLoader: PagerLoader\n\n    override fun onCreateViewInflater(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n    ): FragmentReaderNormalBinding {\n        return FragmentReaderNormalBinding.inflate(inflater, container, false)\n    }\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n        binding.mangaReaderViewpager2.layoutDirection = View.LAYOUT_DIRECTION_LTR\n\n        with(binding.mangaReaderViewpager2) {\n            adapter = readerAdapter\n            offscreenPageLimit = 1\n            onPageChangeCallback {\n                viewModel.onPagePositionChange(it)\n            }\n        }\n    }\n\n    override suspend fun onLoadUrlChangeSuccess(list: List<MangaReaderPage>, state: MangaState?) {\n        coroutineScope {\n            val items = async {\n                requireAdapter().subItems(list)\n                yield()\n            }\n            if (state != null) {\n                val position = list.indexOfFirst {\n                    it.uuid == state.uuid && it.index == state.page\n                }\n                items.await()\n                if (position != -1) {\n                    binding.mangaReaderViewpager2.setCurrentItem(position, false)\n                    viewModel.onPagePositionChange(position)\n                } else {\n                    Snackbar.make(\n                        requireView(),\n                        getString(R.string.no_content),\n                        Snackbar.LENGTH_LONG\n                    )\n                        .show()\n                }\n            } else {\n                items.await()\n            }\n        }\n    }\n\n    override fun createAdapter(): BaseReaderAdapter<*> {\n        return ReaderPageAdapter(\n            owner = viewLifecycleOwner,\n            imageLoader = pagerLoader\n        )\n    }\n\n    override fun currentState(): MangaState? = bindingOrNull()?.run {\n        val adapter = mangaReaderViewpager2.adapter as? BaseReaderAdapter<*>\n        val page = adapter?.getItemOrNull(mangaReaderViewpager2.currentItem) ?: return@run null\n        MangaState(page.uuid ?: return@run null, page.index)\n    }\n\n    override fun moveToPosition(position: Int, smooth: Boolean) {\n        binding.mangaReaderViewpager2.setCurrentItem(\n            position,\n            smooth\n        )\n    }\n\n    override fun moveDelta(delta: Int) {\n        binding.mangaReaderViewpager2.currentItem = binding.mangaReaderViewpager2.currentItem + 1\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonFrameLayout.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.widget.FrameLayout\nimport androidx.annotation.AttrRes\nimport com.shicheeng.copymanga.R\n\nclass WebtoonFrameLayout @JvmOverloads constructor(\n\tcontext: Context,\n\tattrs: AttributeSet? = null,\n\t@AttrRes defStyleAttr: Int = 0,\n) : FrameLayout(context, attrs, defStyleAttr) {\n\n\tprivate val target by lazy(LazyThreadSafetyMode.NONE) {\n\t\tfindViewById<WebtoonImageView>(R.id.biv_pager_webtoon)\n\t}\n\n\tfun dispatchVerticalScroll(dy: Int): Int {\n\t\tif (dy == 0) {\n\t\t\treturn 0\n\t\t}\n\t\tval oldScroll = target.getScroll()\n\t\ttarget.scrollBy(dy)\n\t\treturn target.getScroll() - oldScroll\n\t}\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonImageView.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.content.Context\nimport android.graphics.PointF\nimport android.util.AttributeSet\nimport android.view.View\nimport android.view.ViewParent\nimport androidx.recyclerview.widget.RecyclerView\nimport com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView\n\nprivate const val SCROLL_UNKNOWN = -1\n\nclass WebtoonImageView @JvmOverloads constructor(\n    context: Context,\n    attr: AttributeSet? = null,\n) : SubsamplingScaleImageView(context, attr) {\n\n    private val ct = PointF()\n\n    private var scrollPos = 0\n    private var scrollRange = SCROLL_UNKNOWN\n\n    fun scrollBy(delta: Int) {\n        val maxScroll = getScrollRange()\n        if (maxScroll == 0) {\n            return\n        }\n        val newScroll = scrollPos + delta\n        scrollToInternal(newScroll.coerceIn(0, maxScroll))\n    }\n\n    fun scrollTo(y: Int) {\n        val maxScroll = getScrollRange()\n        if (maxScroll == 0) {\n            resetScaleAndCenter()\n            return\n        }\n        scrollToInternal(y.coerceIn(0, maxScroll))\n    }\n\n    fun getScroll() = scrollPos\n\n    fun getScrollRange(): Int {\n        if (scrollRange == SCROLL_UNKNOWN) {\n            computeScrollRange()\n        }\n        return scrollRange.coerceAtLeast(0)\n    }\n\n    override fun recycle() {\n        scrollRange = SCROLL_UNKNOWN\n        scrollPos = 0\n        super.recycle()\n    }\n\n    override fun getSuggestedMinimumHeight(): Int {\n        var desiredHeight = super.getSuggestedMinimumHeight()\n        if (sHeight == 0) {\n            val parentHeight = parentHeight()\n            if (desiredHeight < parentHeight) {\n                desiredHeight = parentHeight\n            }\n        }\n        return desiredHeight\n    }\n\n    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {\n        val widthSpecMode = MeasureSpec.getMode(widthMeasureSpec)\n        val heightSpecMode = MeasureSpec.getMode(heightMeasureSpec)\n        val parentWidth = MeasureSpec.getSize(widthMeasureSpec)\n        val parentHeight = MeasureSpec.getSize(heightMeasureSpec)\n        val resizeWidth = widthSpecMode != MeasureSpec.EXACTLY\n        val resizeHeight = heightSpecMode != MeasureSpec.EXACTLY\n        var width = parentWidth\n        var height = parentHeight\n        if (sWidth > 0 && sHeight > 0) {\n            if (resizeWidth && resizeHeight) {\n                width = sWidth\n                height = sHeight\n            } else if (resizeHeight) {\n                height = (sHeight.toDouble() / sWidth.toDouble() * width).toInt()\n            } else if (resizeWidth) {\n                width = (sWidth.toDouble() / sHeight.toDouble() * height).toInt()\n            }\n        }\n        width = width.coerceAtLeast(suggestedMinimumWidth)\n        height = height.coerceIn(suggestedMinimumHeight, parentHeight())\n        setMeasuredDimension(width, height)\n    }\n\n    private fun scrollToInternal(pos: Int) {\n        scrollPos = pos\n        ct.set(sWidth / 2f, (height / 2f + pos.toFloat()) / minScale)\n        setScaleAndCenter(minScale, ct)\n    }\n\n    private fun computeScrollRange() {\n        if (!isReady) {\n            return\n        }\n        val totalHeight = (sHeight * minScale).toIntUp()\n        scrollRange = (totalHeight - height).coerceAtLeast(0)\n    }\n\n    private fun parentHeight(): Int {\n        return parents.firstNotNullOfOrNull { it as? RecyclerView }?.height ?: 0\n    }\n}\n\nfun Float.toIntUp(): Int {\n    val intValue = toInt()\n    return if (this == intValue.toFloat()) {\n        intValue\n    } else {\n        intValue + 1\n    }\n}\n\nprivate val View.parents: Sequence<ViewParent>\n    get() = sequence {\n        var p: ViewParent? = parent\n        while (p != null) {\n            yield(p)\n            p = p.parent\n        }\n    }\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonLayoutManager.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport kotlin.math.sign\n\n/**\n * From Kotatsu Reader\n */\n@Suppress(\"unused\")\nclass WebtoonLayoutManager : LinearLayoutManager {\n\n    private var scrollDirection: Int = 0\n\n    constructor(context: Context) : super(context)\n    constructor(\n        context: Context,\n        orientation: Int,\n        reverseLayout: Boolean,\n    ) : super(context, orientation, reverseLayout)\n\n    constructor(\n        context: Context,\n        attrs: AttributeSet?,\n        defStyleAttr: Int,\n        defStyleRes: Int,\n    ) : super(context, attrs, defStyleAttr, defStyleRes)\n\n    override fun scrollVerticallyBy(\n\t\tdy: Int,\n\t\trecycler: RecyclerView.Recycler?,\n\t\tstate: RecyclerView.State,\n\t): Int {\n        scrollDirection = dy.sign\n        return super.scrollVerticallyBy(dy, recycler, state)\n    }\n\n    override fun calculateExtraLayoutSpace(state: RecyclerView.State, extraLayoutSpace: IntArray) {\n        if (state.hasTargetScrollPosition()) {\n            super.calculateExtraLayoutSpace(state, extraLayoutSpace)\n            return\n        }\n        val pageSize = height\n        extraLayoutSpace[0] = if (scrollDirection < 0) pageSize else 0\n        extraLayoutSpace[1] = if (scrollDirection < 0) 0 else pageSize\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonReaderAdapter.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.view.LayoutInflater\nimport android.view.ViewGroup\nimport androidx.lifecycle.LifecycleOwner\nimport com.shicheeng.copymanga.databinding.ItemPageWebtoonBinding\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.BaseReaderAdapter\n\nclass WebtoonReaderAdapter(\n    private val owner: LifecycleOwner,\n    private val imageLoader: PagerLoader,\n) : BaseReaderAdapter<WebtoonReaderViewHolder>() {\n\n    override fun onCreateViewHolder(parent: ViewGroup): WebtoonReaderViewHolder =\n        WebtoonReaderViewHolder(\n            ItemPageWebtoonBinding.inflate(\n                LayoutInflater.from(parent.context),\n                parent,\n                false\n            ), imageLoader, owner\n        )\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonReaderFragment.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.os.Bundle\nimport android.view.LayoutInflater\nimport android.view.View\nimport android.view.ViewGroup\nimport android.view.animation.AccelerateDecelerateInterpolator\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.snackbar.Snackbar\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.MangaState\nimport com.shicheeng.copymanga.databinding.FragmentReaderWebtoonBinding\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.BaseReader\nimport com.shicheeng.copymanga.fm.reader.BaseReaderAdapter\nimport com.shicheeng.copymanga.util.findCurrentPagePosition\nimport com.shicheeng.copymanga.util.firstVisibleItemPosition\nimport com.shicheeng.copymanga.util.setFirstVisibleItemPositionSmooth\nimport dagger.hilt.android.AndroidEntryPoint\nimport kotlinx.coroutines.async\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.yield\nimport javax.inject.Inject\n\n@AndroidEntryPoint\nclass WebtoonReaderFragment : BaseReader<FragmentReaderWebtoonBinding>() {\n\n    private val scrollInterpolator = AccelerateDecelerateInterpolator()\n\n    @Inject\n    lateinit var pagerLoader: PagerLoader\n\n    override fun onCreateViewInflater(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n    ): FragmentReaderWebtoonBinding =\n        FragmentReaderWebtoonBinding.inflate(inflater, container, false)\n\n    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {\n        super.onViewCreated(view, savedInstanceState)\n\n\n        with(binding.mangaReaderWebtoonRecyclerview) {\n            setHasFixedSize(true)\n            adapter = readerAdapter\n            addOnScrollListener(RecyclerViewScrollListener())\n        }\n\n    }\n\n    override fun currentState(): MangaState? = bindingOrNull()?.run {\n        val firstItem = mangaReaderWebtoonRecyclerview.findCurrentPagePosition()\n        val adapter = mangaReaderWebtoonRecyclerview.adapter as? BaseReaderAdapter<*>\n        val page = adapter?.getItemOrNull(firstItem) ?: return@run null\n        MangaState(page.uuid ?: return@run null, page.index)\n    }\n\n    override fun onDestroyView() {\n        requireBinding().mangaReaderWebtoonRecyclerview.adapter = null\n        super.onDestroyView()\n    }\n\n    override fun moveToPosition(position: Int, smooth: Boolean) {\n        binding.mangaReaderWebtoonRecyclerview.setFirstVisibleItemPositionSmooth(\n            position,\n            smooth\n        )\n    }\n\n    override fun moveDelta(delta: Int) {\n        binding.mangaReaderWebtoonRecyclerview.smoothScrollBy(\n            0,\n            (binding.mangaReaderWebtoonRecyclerview.height * 0.9).toInt() * delta,\n            scrollInterpolator,\n        )\n    }\n\n    override suspend fun onLoadUrlChangeSuccess(\n        list: List<MangaReaderPage>,\n        state: MangaState?,\n    ) = coroutineScope {\n        val items = async {\n            requireAdapter().subItems(list)\n            yield()\n        }\n        if (state != null) {\n            val position = list.indexOfFirst {\n                it.uuid == state.uuid && it.index == state.page\n            }\n            items.await()\n            if (position != -1) {\n                with(binding.mangaReaderWebtoonRecyclerview) {\n                    firstVisibleItemPosition = position\n                }\n                viewModel.onPagePositionChange(position)\n            } else {\n                Snackbar.make(requireView(), getString(R.string.no_content), Snackbar.LENGTH_LONG)\n                    .show()\n            }\n        } else {\n            items.await()\n        }\n\n    }\n\n    override fun createAdapter(): BaseReaderAdapter<*> {\n        return WebtoonReaderAdapter(\n            owner = viewLifecycleOwner,\n            imageLoader = pagerLoader\n        )\n    }\n\n    inner class RecyclerViewScrollListener : RecyclerView.OnScrollListener() {\n        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {\n            super.onScrolled(recyclerView, dx, dy)\n            viewModel.onPagePositionChange(recyclerView.findCurrentPagePosition())\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonReaderViewHolder.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.net.Uri\nimport androidx.core.view.isVisible\nimport androidx.lifecycle.LifecycleOwner\nimport com.davemorrissey.labs.subscaleview.ImageSource\nimport com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView\nimport com.davemorrissey.labs.subscaleview.decoder.SkiaPooledImageRegionDecoder\nimport com.shicheeng.copymanga.databinding.ItemPageWebtoonBinding\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.BaseReaderViewHolder\n\nclass WebtoonReaderViewHolder(\n    itemPageWebtoonBinding: ItemPageWebtoonBinding,\n    imageLoader: PagerLoader,\n    owner: LifecycleOwner,\n) : BaseReaderViewHolder<ItemPageWebtoonBinding>(\n    binding = itemPageWebtoonBinding,\n    imageLoader = imageLoader\n) {\n\n    private var url: String? = null\n    private var scrollToRestore = 0\n\n    init {\n        binding.bivPagerWebtoon.bindToLifecycle(owner)\n        binding.bivPagerWebtoon.regionDecoderFactory = SkiaPooledImageRegionDecoder.Factory()\n        binding.bivPagerWebtoon.addOnImageEventListener(delegate)\n    }\n\n    override fun onBind(url: String) {\n        this.url = url\n    }\n\n    override fun onLoadingStarted() {\n        binding.errorLayout.errorTextLayout.isVisible = false\n        bindingInfo.loadIndicator.isVisible = true\n        binding.bivPagerWebtoon.recycle()\n    }\n\n    override fun onError(e: Throwable) {\n        with(binding.errorLayout) {\n            errorTextLayout.isVisible = true\n            errorTextTipDesc.text = e.message\n            btnErrorRetry.setOnClickListener {\n                url?.let { it1 ->\n                    delegate.retry(it1)\n                }\n            }\n        }\n        bindingInfo.loadIndicator.isVisible = false\n    }\n\n    override fun onImageReady(uri: Uri) {\n        binding.bivPagerWebtoon.setImage(ImageSource.Uri(uri))\n    }\n\n    override fun onImageShowing() {\n        with(binding.bivPagerWebtoon) {\n            minimumScaleType = SubsamplingScaleImageView.SCALE_TYPE_CUSTOM\n            minScale = width / sWidth.toFloat()\n            maxScale = minScale\n            scrollTo(\n                when {\n                    scrollToRestore != 0 -> scrollToRestore\n                    itemView.top < 0 -> getScrollRange()\n                    else -> 0\n                },\n            )\n            scrollToRestore = 0\n        }\n    }\n\n    override fun onImageShown() {\n        bindingInfo.loadIndicator.isVisible = false\n        binding.errorLayout.errorTextLayout.isVisible = false\n    }\n\n    override fun onRecycler() {\n        super.onRecycler()\n        binding.bivPagerWebtoon.recycle()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonRecyclerView.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport androidx.core.view.ViewCompat.TYPE_TOUCH\nimport androidx.recyclerview.widget.RecyclerView\nimport com.shicheeng.copymanga.util.findCurrentPagePosition\nimport java.util.LinkedList\n\nclass WebtoonRecyclerView @JvmOverloads constructor(\n\tcontext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0,\n) : RecyclerView(context, attrs, defStyleAttr) {\n\n    private var onPageScrollListeners: MutableList<OnPageScrollListener>? = null\n\n    override fun startNestedScroll(axes: Int) = startNestedScroll(axes, TYPE_TOUCH)\n\n    override fun startNestedScroll(axes: Int, type: Int): Boolean = true\n\n    override fun dispatchNestedPreScroll(\n\t\tdx: Int,\n\t\tdy: Int,\n\t\tconsumed: IntArray?,\n\t\toffsetInWindow: IntArray?,\n\t) = dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow, TYPE_TOUCH)\n\n    override fun dispatchNestedPreScroll(\n\t\tdx: Int,\n\t\tdy: Int,\n\t\tconsumed: IntArray?,\n\t\toffsetInWindow: IntArray?,\n\t\ttype: Int,\n\t): Boolean {\n        val consumedY = consumeVerticalScroll(dy)\n        if (consumed != null) {\n            consumed[0] = 0\n            consumed[1] = consumedY\n        }\n        notifyScrollChanged(dy)\n        return consumedY != 0 || dy == 0\n    }\n\n    private fun consumeVerticalScroll(dy: Int): Int {\n        if (childCount == 0) {\n            return 0\n        }\n        when {\n            dy > 0 -> {\n                val child = getChildAt(0) as WebtoonFrameLayout\n                var consumedByChild = child.dispatchVerticalScroll(dy)\n                if (consumedByChild < dy) {\n                    if (childCount > 1) {\n                        val nextChild = getChildAt(1) as WebtoonFrameLayout\n                        val unconsumed =\n                            dy - consumedByChild - nextChild.top //will be consumed by scroll\n                        if (unconsumed > 0) {\n                            consumedByChild += nextChild.dispatchVerticalScroll(unconsumed)\n                        }\n                    }\n                }\n                return consumedByChild\n            }\n\n            dy < 0 -> {\n                val child = getChildAt(childCount - 1) as WebtoonFrameLayout\n                var consumedByChild = child.dispatchVerticalScroll(dy)\n                if (consumedByChild > dy) {\n                    if (childCount > 1) {\n                        val nextChild = getChildAt(childCount - 2) as WebtoonFrameLayout\n                        val unconsumed =\n                            dy - consumedByChild + (height - nextChild.bottom) //will be consumed by scroll\n                        if (unconsumed < 0) {\n                            consumedByChild += nextChild.dispatchVerticalScroll(unconsumed)\n                        }\n                    }\n                }\n                return consumedByChild\n            }\n        }\n        return 0\n    }\n\n    fun addOnPageScrollListener(listener: OnPageScrollListener) {\n        val list = onPageScrollListeners\n            ?: LinkedList<OnPageScrollListener>().also { onPageScrollListeners = it }\n        list.add(listener)\n    }\n\n    fun removeOnPageScrollListener(listener: OnPageScrollListener) {\n        onPageScrollListeners?.remove(listener)\n    }\n\n    private fun notifyScrollChanged(dy: Int) {\n        val listeners = onPageScrollListeners\n        if (listeners.isNullOrEmpty()) {\n            return\n        }\n        val centerPosition = findCurrentPagePosition()\n        listeners.forEach { it.dispatchScroll(this, dy, centerPosition) }\n    }\n\n    abstract class OnPageScrollListener {\n\n        private var lastPosition = NO_POSITION\n\n        fun dispatchScroll(recyclerView: WebtoonRecyclerView, dy: Int, centerPosition: Int) {\n            onScroll(recyclerView, dy)\n            if (centerPosition != NO_POSITION && centerPosition != lastPosition) {\n                lastPosition = centerPosition\n                onPageChanged(recyclerView, centerPosition)\n            }\n        }\n\n        open fun onScroll(recyclerView: WebtoonRecyclerView, dy: Int) = Unit\n\n        open fun onPageChanged(recyclerView: WebtoonRecyclerView, index: Int) = Unit\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/fm/reader/webtoon/WebtoonScalingFrame.kt",
    "content": "package com.shicheeng.copymanga.fm.reader.webtoon\n\nimport android.animation.ObjectAnimator\nimport android.content.Context\nimport android.graphics.Matrix\nimport android.graphics.Rect\nimport android.graphics.RectF\nimport android.util.AttributeSet\nimport android.view.GestureDetector\nimport android.view.MotionEvent\nimport android.view.ScaleGestureDetector\nimport android.view.animation.AccelerateDecelerateInterpolator\nimport android.widget.FrameLayout\nimport android.widget.OverScroller\nimport androidx.core.view.GestureDetectorCompat\n\nprivate const val MAX_SCALE = 2.5f\nprivate const val MIN_SCALE = 1f // under-scaling disabled due to buggy nested scroll\n\nclass WebtoonScalingFrame @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    defStyles: Int = 0,\n) : FrameLayout(context, attrs, defStyles), ScaleGestureDetector.OnScaleGestureListener {\n\n    private val targetChild by lazy(LazyThreadSafetyMode.NONE) { getChildAt(0) }\n\n    private val scaleDetector = ScaleGestureDetector(context, this)\n    private val gestureDetector = GestureDetectorCompat(context, GestureListener())\n    private val overScroller = OverScroller(context, AccelerateDecelerateInterpolator())\n    private val transformMatrix = Matrix()\n    private val matrixValues = FloatArray(9)\n    private val scale\n        get() = matrixValues[Matrix.MSCALE_X]\n    private val transX\n        get() = halfWidth * (scale - 1f) + matrixValues[Matrix.MTRANS_X]\n    private val transY\n        get() = halfHeight * (scale - 1f) + matrixValues[Matrix.MTRANS_Y]\n    private var halfWidth = 0f\n    private var halfHeight = 0f\n    private val translateBounds = RectF()\n    private val targetHitRect = Rect()\n    private var pendingScroll = 0\n\n    var isZoomEnable = true\n        set(value) {\n            field = value\n            if (scale != 1f) {\n                scaleChild(1f, halfWidth, halfHeight)\n            }\n        }\n\n    init {\n        syncMatrixValues()\n    }\n\n    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {\n        if (!isZoomEnable || ev == null) {\n            return super.dispatchTouchEvent(ev)\n        }\n\n        if (ev.action == MotionEvent.ACTION_DOWN && overScroller.computeScrollOffset()) {\n            overScroller.forceFinished(true)\n        }\n\n        gestureDetector.onTouchEvent(ev)\n        scaleDetector.onTouchEvent(ev)\n\n        // Offset event to inside the child view\n        if (scale < 1 && !targetHitRect.contains(ev.x.toInt(), ev.y.toInt())) {\n            ev.offsetLocation(halfWidth - ev.x + targetHitRect.width() / 3, 0f)\n        }\n\n        // Send action cancel to avoid recycler jump when scale end\n        if (scaleDetector.isInProgress) {\n            ev.action = MotionEvent.ACTION_CANCEL\n        }\n        return super.dispatchTouchEvent(ev)\n    }\n\n    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec)\n        halfWidth = measuredWidth / 2f\n        halfHeight = measuredHeight / 2f\n    }\n\n    private fun invalidateTarget() {\n        adjustBounds()\n        targetChild.run {\n            scaleX = scale\n            scaleY = scale\n            translationX = transX\n            translationY = transY\n        }\n\n        val newHeight = if (scale < 1f) (height / scale).toInt() else height\n        if (newHeight != targetChild.height) {\n            targetChild.layoutParams.height = newHeight\n            targetChild.requestLayout()\n        }\n\n        if (scale < 1) {\n            targetChild.getHitRect(targetHitRect)\n            targetChild.scrollBy(0, pendingScroll)\n            pendingScroll = 0\n        }\n    }\n\n    private fun syncMatrixValues() {\n        transformMatrix.getValues(matrixValues)\n    }\n\n    private fun adjustBounds() {\n        syncMatrixValues()\n        val dx = when {\n            transX < translateBounds.left -> translateBounds.left - transX\n            transX > translateBounds.right -> translateBounds.right - transX\n            else -> 0f\n        }\n\n        val dy = when {\n            transY < translateBounds.top -> translateBounds.top - transY\n            transY > translateBounds.bottom -> translateBounds.bottom - transY\n            else -> 0f\n        }\n\n        pendingScroll = dy.toInt()\n        transformMatrix.postTranslate(dx, dy)\n        syncMatrixValues()\n    }\n\n    private fun scaleChild(newScale: Float, focusX: Float, focusY: Float) {\n        val factor = newScale / scale\n        if (newScale > 1) {\n            translateBounds.set(\n                halfWidth * (1 - newScale),\n                halfHeight * (1 - newScale),\n                halfWidth * (newScale - 1),\n                halfHeight * (newScale - 1),\n            )\n        } else {\n            translateBounds.set(\n                0f,\n                halfHeight - halfHeight / newScale,\n                0f,\n                halfHeight - halfHeight / newScale,\n            )\n        }\n        transformMatrix.postScale(factor, factor, focusX, focusY)\n        invalidateTarget()\n    }\n\n\n    override fun onScale(detector: ScaleGestureDetector): Boolean {\n        val newScale = (scale * detector.scaleFactor).coerceIn(MIN_SCALE, MAX_SCALE)\n        scaleChild(newScale, detector.focusX, detector.focusY)\n        return true\n    }\n\n    override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true\n\n    override fun onScaleEnd(p0: ScaleGestureDetector) {\n        pendingScroll = 0\n    }\n\n\n    private inner class GestureListener : GestureDetector.SimpleOnGestureListener(), Runnable {\n\n        override fun onScroll(\n            e1: MotionEvent?,\n            e2: MotionEvent,\n            distanceX: Float,\n            distanceY: Float,\n        ): Boolean {\n            if (scale <= 1f) return false\n            transformMatrix.postTranslate(-distanceX, -distanceY)\n            invalidateTarget()\n            return true\n        }\n\n        override fun onDoubleTap(e: MotionEvent): Boolean {\n            val newScale = if (scale != 1f) 1f else MAX_SCALE * 0.8f\n            ObjectAnimator.ofFloat(scale, newScale).run {\n                interpolator = AccelerateDecelerateInterpolator()\n                duration = 300\n                addUpdateListener {\n                    scaleChild(it.animatedValue as Float, e.x, e.y)\n                }\n                start()\n            }\n            return true\n        }\n\n        override fun onFling(\n            e1: MotionEvent?,\n            e2: MotionEvent,\n            velocityX: Float,\n            velocityY: Float,\n        ): Boolean {\n            if (scale <= 1) return false\n\n            overScroller.fling(\n                transX.toInt(),\n                transY.toInt(),\n                velocityX.toInt(),\n                velocityY.toInt(),\n                translateBounds.left.toInt(),\n                translateBounds.right.toInt(),\n                translateBounds.top.toInt(),\n                translateBounds.bottom.toInt(),\n            )\n            postOnAnimation(this)\n            return true\n        }\n\n        override fun run() {\n            if (overScroller.computeScrollOffset()) {\n                transformMatrix.postTranslate(\n                    overScroller.currX - transX, overScroller.currY - transY\n                )\n                invalidateTarget()\n                postOnAnimation(this)\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/json/MainBannerJson.kt",
    "content": "package com.shicheeng.copymanga.json\n\nimport com.google.gson.JsonArray\nimport com.google.gson.JsonObject\nimport com.shicheeng.copymanga.data.BannerList\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.parserToJson\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MainBannerJson @Inject constructor(\n    private val settingPref: SettingPref,\n) {\n\n    private val apiHeader\n        get() = settingPref.apiSelected\n    private val mainPageUrl =\n        \"https://api.$apiHeader/api/v3/h5/homeIndex?platform=3&amp;format=json\"\n\n    @Inject\n    lateinit var okHttpClient: OkHttpClient\n\n    suspend fun fetchMainListData(): JsonObject = withContext(Dispatchers.Default) {\n        val request: Request = Request.Builder()\n            .url(mainPageUrl)\n            .build()\n        okHttpClient.newCall(request).execute().use { response ->\n            val jsonData = requireNotNull(response.body).string()\n            jsonData.parserToJson().asJsonObject.getAsJsonObject(\"results\")\n        }\n    }\n\n\n    fun getBannerMain(jsonObject: JsonObject): ArrayList<BannerList> {\n        val array1 = jsonObject[\"banners\"].asJsonArray\n        val bannerLists = ArrayList<BannerList>()\n        for (ele in array1) {\n            val element = ele.asJsonObject[\"type\"]\n            if (element.asInt == 1) {\n                val list = BannerList()\n                list.jsonObject = ele.asJsonObject\n                bannerLists.add(list)\n            }\n        }\n        return bannerLists\n    }\n\n    fun getRecMain(jsonObject: JsonObject): JsonArray =\n        jsonObject[\"recComics\"].asJsonObject.getAsJsonArray(\"list\")\n\n    fun getHotMain(jsonObject: JsonObject): JsonArray = jsonObject[\"hotComics\"].asJsonArray\n\n    fun getNewMain(jsonObject: JsonObject): JsonArray = jsonObject[\"newComics\"].asJsonArray\n\n    fun getFinishMain(jsonObject: JsonObject): JsonArray {\n        return jsonObject.getAsJsonObject(\"finishComics\").getAsJsonArray(\"list\")\n    }\n\n    fun getRecTopic(jsonObject: JsonObject): JsonArray {\n        return jsonObject[\"topics\"].asJsonObject[\"list\"].asJsonArray\n    }\n\n    fun getDayRankMain(jsonObject: JsonObject): HashMap<Int, JsonArray> {\n        val map = HashMap<Int, JsonArray>()\n        map[0] = jsonObject[\"rankDayComics\"].asJsonObject.getAsJsonArray(\"list\")\n        map[1] = jsonObject[\"rankWeekComics\"].asJsonObject.getAsJsonArray(\"list\")\n        map[2] = jsonObject[\"rankMonthComics\"].asJsonObject.getAsJsonArray(\"list\")\n        return map\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/json/MangaSortJson.kt",
    "content": "package com.shicheeng.copymanga.json\n\nimport com.shicheeng.copymanga.data.MangaSortBean\n\nenum class MangaSortJson {\n\n    ORDER, THEME, PATH;\n\n    companion object {\n        @JvmStatic\n        val order: List<MangaSortBean>\n            get() {\n                val list: MutableList<MangaSortBean> = ArrayList()\n                val bean1 = MangaSortBean()\n                bean1.pathName = \"最久更新\"\n                bean1.pathWord = \"datetime_updated\"\n                list.add(bean1)\n                val dateUpdateNearly = MangaSortBean()\n                dateUpdateNearly.pathName = \"最近更新\"\n                dateUpdateNearly.pathWord = \"-datetime_updated\"\n                list.add(dateUpdateNearly)\n                val bean2 = MangaSortBean()\n                bean2.pathName = \"最热\"\n                bean2.pathWord = \"-popular\"\n                list.add(bean2)\n                val unpopular = MangaSortBean()\n                unpopular.pathName = \"最冷\"\n                unpopular.pathWord = \"popular\"\n                list.add(unpopular)\n                return list\n            }\n\n        @JvmStatic\n        val topPath = listOf(\n            MangaSortBean(\"无\", \"\"),\n            MangaSortBean(\"日本\", \"japan\"),\n            MangaSortBean(\"已完结\", \"finish\"),\n            MangaSortBean(\"韩国\", \"korea\"),\n            MangaSortBean(\"欧美\", \"west\"),\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/json/UpdateMetaDataJson.kt",
    "content": "package com.shicheeng.copymanga.json\n\nimport com.shicheeng.copymanga.BuildConfig\nimport com.shicheeng.copymanga.data.VersionUnit\nimport com.shicheeng.copymanga.data.versionId\nimport com.shicheeng.copymanga.util.asArrayList\nimport com.shicheeng.copymanga.util.await\nimport com.shicheeng.copymanga.util.parserAsJson\nimport com.shicheeng.copymanga.util.timeStampConvert\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.withContext\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okhttp3.Response\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass UpdateMetaDataJson @Inject constructor(\n    private val okHttpClient: OkHttpClient,\n) {\n\n    private val updateMetadata =\n        \"https://api.github.com/repos/shizheng233/CopyMangaJava/releases?page=1&per_page=10\"\n\n    private val availableUpdate = MutableStateFlow<VersionUnit?>(null)\n\n    fun availableUpdateVersion() = availableUpdate.asStateFlow()\n\n    private suspend fun getUpdateInfoVersion(): List<VersionUnit> {\n        val request = Request.Builder().url(updateMetadata).build()\n        val call = okHttpClient.newCall(request)\n        val res = call.await()\n        return buildList {\n            mapToList(res) {\n                add(it)\n            }\n        }\n    }\n\n\n    suspend fun fetchUpdate(): VersionUnit? = withContext(Dispatchers.Default) {\n        runCatching {\n            val thisVersion = versionId(BuildConfig.VERSION_NAME)\n            val allVersion = getUpdateInfoVersion().asArrayList()\n            allVersion.sortBy { it.versionId }\n            allVersion.maxByOrNull { it.versionId }?.takeIf {\n                it.versionId > thisVersion\n            }\n        }.onFailure {\n            it.printStackTrace()\n        }.onSuccess {\n            availableUpdate.emit(it)\n        }.getOrNull()\n    }\n\n    private inline fun mapToList(\n        response: Response,\n        crossinline block: (VersionUnit) -> Unit,\n    ) {\n        val json = response.body?.string()?.parserAsJson()?.asJsonArray ?: return\n        for (element in json) {\n            val singleObj = element.asJsonObject\n            val arrest = singleObj[\"assets\"].asJsonArray[0].asJsonObject\n            val versionName = singleObj[\"tag_name\"].asString\n            val url = arrest[\"browser_download_url\"].asString\n            val apkSize = arrest[\"size\"].asLong\n            val htmlUrl = singleObj[\"html_url\"].asString\n            val id = singleObj[\"id\"].asLong\n            val time = singleObj[\"published_at\"].asString.timeStampConvert()\n            val description = singleObj[\"body\"].asString\n            val versionUnit = VersionUnit(id, htmlUrl, versionName, url, apkSize, description, time)\n            block(versionUnit)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/modula/CopyMangaApiModula.kt",
    "content": "package com.shicheeng.copymanga.modula\n\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.components.SingletonComponent\nimport okhttp3.OkHttpClient\nimport retrofit2.Retrofit\nimport retrofit2.converter.moshi.MoshiConverterFactory\nimport javax.inject.Singleton\n\n\n@Module\n@InstallIn(SingletonComponent::class)\nobject CopyMangaApiModula {\n\n\n    @Provides\n    @Singleton\n    fun provideCopyMangaApi(\n        retrofit: Retrofit,\n    ): CopyMangaApi {\n        return retrofit.create(CopyMangaApi::class.java)\n    }\n\n    @Provides\n    @Singleton\n    fun provideRetrofit(\n        settingPref: SettingPref,\n        okHttpClient: OkHttpClient,\n    ): Retrofit {\n        val headerTheKey = \"https://api.\"\n        val apiName = settingPref.apiSelected\n        return Retrofit.Builder()\n            .client(okHttpClient)\n            .baseUrl(\"$headerTheKey$apiName\")\n            .addConverterFactory(MoshiConverterFactory.create())\n            .build()\n    }\n\n\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/modula/LoginRoomModula.kt",
    "content": "package com.shicheeng.copymanga.modula\n\nimport android.content.Context\nimport androidx.room.Room\nimport androidx.room.migration.Migration\nimport androidx.sqlite.db.SupportSQLiteDatabase\nimport com.shicheeng.copymanga.database.MangaLoginDatabase\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@InstallIn(SingletonComponent::class)\n@Module\nobject LoginRoomModula {\n\n    @Provides\n    @Singleton\n    fun initDatabase(@ApplicationContext context: Context): MangaLoginDatabase {\n        return Room.databaseBuilder(\n            context = context,\n            klass = MangaLoginDatabase::class.java,\n            name = \"login_data\"\n        )\n            .addMigrations(_version1to2)\n            .build()\n    }\n\n    @Provides\n    @Singleton\n    fun provideLoginDao(mangaLoginDatabase: MangaLoginDatabase) = mangaLoginDatabase.loginDao()\n\n}\n\nprivate val _version1to2 = object : Migration(1, 2) {\n    override fun migrate(db: SupportSQLiteDatabase) {\n        db.execSQL(\"ALTER TABLE LocalLoginDataModel ADD COLUMN isExpired INTEGER NOT NULL DEFAULT 0\")\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/modula/OkhttpProvider.kt",
    "content": "package com.shicheeng.copymanga.modula\n\nimport android.content.Context\nimport coil.ImageLoader\nimport com.shicheeng.copymanga.resposity.LoginTokenRepository\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.KeyWordSwap\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport dagger.hilt.components.SingletonComponent\nimport okhttp3.Headers\nimport okhttp3.OkHttpClient\nimport javax.inject.Singleton\n\nprivate val queryUrlRegex = \"/api/v3/comic2/.*/query\".toRegex()\nprivate val comic2UrlRegex = \"/api/v3/comic/.*/chapter2/.*\".toRegex()\n\n@Module\n@InstallIn(SingletonComponent::class)\nobject OkhttpProvider {\n\n    @Singleton\n    @Provides\n    fun provideImageLoader(\n        @ApplicationContext context: Context,\n        okHttpClient: OkHttpClient,\n    ): ImageLoader {\n        return ImageLoader.Builder(context).okHttpClient(okHttpClient).build()\n    }\n\n    @Provides\n    @Singleton\n    fun headersProvide(\n        settingPref: SettingPref,\n    ): Headers = Headers.Builder()\n        .add(\n            \"region\",\n            if (settingPref.useForeignApi) \"1\" else \"0\"\n        )\n        .add(\"webp\", \"0\")\n        .add(\"platform\", \"1\")\n        .add(\"version\", \"2023.08.14\")\n        .add(\"referer\", \"https://www.copymanga.site/\")\n        .add(KeyWordSwap.USER_AGENT_WORD, KeyWordSwap.FAKE_USER_AGENT)\n        .build()\n\n    @Provides\n    @Singleton\n    fun provideOkhttp(\n        headers: Headers,\n        loginTokenRepository: LoginTokenRepository,\n    ): OkHttpClient {\n        return OkHttpClient.Builder()\n            .addInterceptor { chain ->\n                val oldRequest = chain.request()\n                val token = loginTokenRepository.token\n                // TODO 能否使用更简单的方式来进行判断\n                val headersNew = if (\n                    (oldRequest.url.toUrl().path == \"/api/v3/member/browse/comics\" ||\n                            oldRequest.url.toUrl().path == \"/api/v3/member/collect/comics\" ||\n                            oldRequest.url.toUrl().path == \"/api/v3/member/update/info\" ||\n                            oldRequest.url.toUrl().path.matches(queryUrlRegex) ||\n                            oldRequest.url.toUrl().path.matches(comic2UrlRegex) ||\n                            oldRequest.url.toUrl().path == \"/api/v3/member/info\" ||\n                            oldRequest.url.toUrl().path == \"/api/v3/member/collect/comic\" ||\n                            oldRequest.url.toUrl().path == \"/api/v3/member/comment\")\n                    && token != null && !loginTokenRepository.isExpired\n                ) {\n                    headers.newBuilder()\n                        .add(\"Authorization\", \"Token $token\")\n                        .build()\n                } else {\n                    headers\n                }\n\n                val newRequest = oldRequest.newBuilder().headers(headersNew)\n                chain.proceed(newRequest.build())\n            }\n            .build()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/modula/RoomModula.kt",
    "content": "package com.shicheeng.copymanga.modula\n\nimport android.content.Context\nimport androidx.room.Room\nimport androidx.room.migration.Migration\nimport androidx.sqlite.db.SupportSQLiteDatabase\nimport com.shicheeng.copymanga.database.MangaHistoryDataBase\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\nobject RoomModula {\n\n    @Provides\n    @Singleton\n    fun provideHistoryDataBase(@ApplicationContext context: Context) = Room\n        .databaseBuilder(\n            context = context,\n            klass = MangaHistoryDataBase::class.java,\n            name = \"manga_history_database_2\"\n        ).addMigrations(\n            VERSION1to2,\n            VERSION2to3,\n            VERSION3to4,\n            VERSION4to5,\n            VERSION5to6\n        ).build()\n\n    @Provides\n    @Singleton\n    fun provideHistoryDao(mangaHistoryDataBase: MangaHistoryDataBase) =\n        mangaHistoryDataBase.historyDao()\n\n    @Provides\n    @Singleton\n    fun provideKeyWordHistoryDao(mangaHistoryDataBase: MangaHistoryDataBase) =\n        mangaHistoryDataBase.keyWordDao()\n\n}\n\n/**\n * 迁移新的历史记录，该历史记录保存更加详细的内容。\n */\nobject VERSION1to2 : Migration(1, 2) {\n    override fun migrate(database: SupportSQLiteDatabase) {\n        //for local information\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN alias TEXT NULL DEFAULT NULL\")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN mangaDetail TEXT NOT NULL DEFAULT \\\"空\\\" \")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN mangaStatus TEXT NOT NULL DEFAULT \\\"空\\\" \")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN authorList TEXT NOT NULL DEFAULT \\\"空\\\"\")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN themeList TEXT NOT NULL DEFAULT \\\"空\\\"\")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN mangaStatusId INTEGER NOT NULL DEFAULT 0\")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN mangaRegion TEXT NOT NULL DEFAULT \\\"空\\\"\")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN mangaLastUpdate TEXT NOT NULL DEFAULT \\\"空\\\"\")\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN mangaPopularNumber TEXT NOT NULL DEFAULT \\\"空\\\"\")\n\n        //for local chapter\n        database.execSQL(\n            \"CREATE TABLE LocalChapter (\" +\n                    \"uuid TEXT PRIMARY KEY NOT NULL,\" +\n                    \"groupId TEXT NULL DEFAULT NULL,\" +\n                    \"comicId TEXT NOT NULL,\" +\n                    \"comicPathWord TEXT NOT NULL,\" +\n                    \"groupPathWord TEXT NOT NULL,\" +\n                    \"name TEXT NOT NULL,\" +\n                    \"imgType INTEGER NOT NULL,\" +\n                    \"isReadProgress INTEGER NOT NULL,\" +\n                    \"next TEXT NULL,\" +\n                    \"ordered INTEGER NOT NULL,\" +\n                    \"prev TEXT NULL,\" +\n                    \"type INTEGER NOT NULL,\" +\n                    \"size INTEGER NOT NULL,\" +\n                    \"datetime_created TEXT NOT NULL,\" +\n                    \"count INTEGER NOT NULL,\" +\n                    \"readIndex INTEGER NOT NULL,\" +\n                    \"news TEXT NOT NULL,\" +\n                    \"`index` INTEGER NOT NULL\" +\n                    \")\"\n        )\n    }\n}\n\n/**\n * 迁移到新的版本\n */\nobject VERSION2to3 : Migration(2, 3) {\n    override fun migrate(database: SupportSQLiteDatabase) {\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN isSubscribe INTEGER NOT NULL DEFAULT 0\")\n        database.execSQL(\"ALTER TABLE LocalChapter ADD COLUMN isDownloaded INTEGER NOT NULL DEFAULT 0\")\n    }\n\n}\n\n/**\n * 加入搜索历史\n */\nobject VERSION3to4 : Migration(3, 4) {\n\n    override fun migrate(database: SupportSQLiteDatabase) {\n        database.execSQL(\n            \"CREATE TABLE SearchHistory (\" +\n                    \"word TEXT PRIMARY KEY NOT NULL,\" +\n                    \"time INTEGER NOT NULL\" +\n                    \")\"\n        )\n    }\n\n}\n\n/**\n * 加入阅读完成\n */\nobject VERSION4to5 : Migration(4, 5) {\n    override fun migrate(database: SupportSQLiteDatabase) {\n        database.execSQL(\"ALTER TABLE LocalChapter ADD COLUMN isReadFinish INTEGER NOT NULL DEFAULT 0\")\n    }\n}\n\nobject VERSION5to6 : Migration(5, 6) {\n    override fun migrate(database: SupportSQLiteDatabase) {\n        database.execSQL(\"ALTER TABLE manga_history_key ADD COLUMN comicUUID TEXT NOT NULL DEFAULT \\\"unknown\\\" \")\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/modula/WorkerModula.kt",
    "content": "package com.shicheeng.copymanga.modula\n\nimport android.content.Context\nimport androidx.work.WorkManager\nimport coil.ImageLoader\nimport dagger.Module\nimport dagger.Provides\nimport dagger.hilt.InstallIn\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport dagger.hilt.components.SingletonComponent\nimport javax.inject.Singleton\n\n@Module\n@InstallIn(SingletonComponent::class)\nobject WorkerModula {\n\n\n\n    @Singleton\n    @Provides\n    fun provideWorkerManager(\n        @ApplicationContext context: Context,\n    ): WorkManager {\n        return WorkManager.getInstance(context)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/AuthorsMangaPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.authormanga.AuthorMangaItem\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport kotlin.coroutines.Continuation\n\nclass AuthorsMangaPagingSource(\n    private val pathWord: String,\n    private val copyMangaApi: CopyMangaApi,\n) : PagingSource<Int, AuthorMangaItem>() {\n    override fun getRefreshKey(state: PagingState<Int, AuthorMangaItem>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, AuthorMangaItem> {\n        val offset = params.key ?: 0\n\n        return try {\n            val data = copyMangaApi.comicAuthors(author = pathWord, offset = offset)\n            LoadResult.Page(\n                data = data.results.list,\n                nextKey = if (data.results.offset > data.results.total) null else offset + 21,\n                prevKey = null\n            )\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LoadResult.Error(e)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/ComicCommentPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.mangacomment.MangaCommentListItem\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass ComicCommentPagingSource(\n    private val uuid: String,\n    private val copyMangaApi: CopyMangaApi,\n) : PagingSource<Int, MangaCommentListItem>() {\n\n    override fun getRefreshKey(state: PagingState<Int, MangaCommentListItem>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MangaCommentListItem> {\n        val offset = params.key ?: 0\n        return try {\n            val model = copyMangaApi.comicComments(comicID = uuid, offset = offset)\n            LoadResult.Page(\n                data = model.results.list,\n                prevKey = null,\n                nextKey = if (model.results.offset > model.results.total) null else offset + 20\n            )\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LoadResult.Error(e)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/ExplorePagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.finished.Item\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass ExplorePagingSource(\n    private val copyMangaApi: CopyMangaApi,\n    private val order: String?,\n    private val themeWord: String?,\n    private val top: String?,\n) : PagingSource<Int, Item>() {\n\n    override fun getRefreshKey(state: PagingState<Int, Item>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {\n        return try {\n            val offset = params.key ?: 0\n            val data = copyMangaApi.fetchMangaFilter(\n                offset = offset,\n                ordering = order,\n                theme = themeWord,\n                top = top\n            )\n            if (offset <= data.results.total) {\n                LoadResult.Page(data.results.list, null, offset + 21)\n            } else {\n                LoadResult.Page(data.results.list, null, null)\n            }\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LoadResult.Error(e)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/FinishedPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.finished.Item\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.json.MangaSortJson\n\nclass FinishedPagingSource(\n    private val copyMangaApi: CopyMangaApi,\n) : PagingSource<Int, Item>() {\n\n    override fun getRefreshKey(state: PagingState<Int, Item>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {\n        return try {\n            val offset = params.key ?: 0\n            val data = copyMangaApi.fetchMangaFilter(\n                offset = offset,\n                top = MangaSortJson.topPath.find { x ->\n                    x.pathName == \"已完结\"\n                }?.pathWord\n            )\n            if (offset <= data.results.total) {\n                LoadResult.Page(data.results.list, null, offset + 21)\n            } else {\n                LoadResult.Page(data.results.list, null, null)\n            }\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/HotPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.finished.Item\nimport com.shicheeng.copymanga.resposity.MangaHotRepository\n\nclass HotPagingSource(\n    private val repository: MangaHotRepository,\n) : PagingSource<Int, Item>() {\n\n    override fun getRefreshKey(state: PagingState<Int, Item>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {\n        return try {\n            val offset = params.key ?: 0\n            val data = repository.fetchHotMangas(offset)\n            if (offset <= data.results.total) {\n                LoadResult.Page(data.results.list, null, offset + 21)\n            } else {\n                LoadResult.Page(data.results.list, null, null)\n            }\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/MangaTopicListPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.topicalllist.TopicAllListItem\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass MangaTopicListPagingSource(\n    private val copyMangaApi: CopyMangaApi,\n) : PagingSource<Int, TopicAllListItem>() {\n\n    override fun getRefreshKey(state: PagingState<Int, TopicAllListItem>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TopicAllListItem> {\n        val offset = params.key ?: 0\n        return try {\n            val data = copyMangaApi.fetchAllTopicListItem(offset = offset)\n            LoadResult.Page(\n                data = data.results.list,\n                prevKey = null,\n                nextKey = if (data.results.offset >= data.results.total) null else offset + 21\n            )\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LoadResult.Error(e)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/NewestPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.newsest.MangaBlock\nimport com.shicheeng.copymanga.resposity.MangaNewestRepository\n\nclass NewestPagingSource(\n    private val repository: MangaNewestRepository,\n) : PagingSource<Int, MangaBlock>() {\n\n    override fun getRefreshKey(state: PagingState<Int, MangaBlock>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, MangaBlock> {\n        return try {\n            val offset = params.key ?: 0\n            val data = repository.fetchNewestMangas(offset)\n            if (offset <= data.results.total) {\n                LoadResult.Page(data.results.list, null, offset + 21)\n            } else {\n                LoadResult.Page(data.results.list, null, null)\n            }\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/RankPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.rank.Item\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass RankPagingSource(\n    private val copyMangaApi: CopyMangaApi,\n    private val rankType: String,\n) : PagingSource<Int, Item>() {\n\n    override fun getRefreshKey(state: PagingState<Int, Item>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {\n        return try {\n            val nextPageKey = params.key ?: 0\n            val ranks = copyMangaApi.getRank(offset = nextPageKey, dateType = rankType)\n            if (nextPageKey <= ranks.results.total) {\n                LoadResult.Page(ranks.results.list, prevKey = null, nextKey = nextPageKey + 21)\n            } else {\n                LoadResult.Page(emptyList(), prevKey = null, nextKey = null)\n            }\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/RecommendPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.recommend.RecommendDataModel\nimport com.shicheeng.copymanga.resposity.MangaRecommendRepository\n\nclass RecommendPagingSource(\n    private val recommendRepository: MangaRecommendRepository,\n) : PagingSource<Int, RecommendDataModel.Results.Item>() {\n\n    override fun getRefreshKey(state: PagingState<Int, RecommendDataModel.Results.Item>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, RecommendDataModel.Results.Item> {\n        return try {\n            val nextPageNumber = params.key ?: 0\n            val responseData = recommendRepository.fetchRecommendMangas(nextPageNumber)\n            if (nextPageNumber <= responseData.results.total) {\n                LoadResult.Page(\n                    data = responseData.results.list,\n                    prevKey = null,\n                    nextKey = nextPageNumber + 21\n                )\n            } else {\n                LoadResult.Page(data = emptyList(), prevKey = null, nextKey = null)\n            }\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/SearchResultPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.search.SearchResultDataModel\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass SearchResultPagingSource(\n    private val word: String,\n    private val copyMangaApi: CopyMangaApi,\n) : PagingSource<Int, SearchResultDataModel>() {\n\n    override fun getRefreshKey(state: PagingState<Int, SearchResultDataModel>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, SearchResultDataModel> {\n        return try {\n            val nextPageNumber = params.key ?: 0\n            val responseData = copyMangaApi.search(q = word, offset = nextPageNumber)\n            if (nextPageNumber <= responseData.results.total) {\n                LoadResult.Page(\n                    data = responseData.results.list,\n                    prevKey = null,\n                    nextKey = nextPageNumber + 21\n                )\n            } else {\n                LoadResult.Page(data = responseData.results.list, prevKey = null, nextKey = null)\n            }\n        } catch (e: Exception) {\n            LoadResult.Error(e)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/TopicDetailListPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.topiclist.TopicItem\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass TopicDetailListPagingSource(\n    private val copyMangaApi: CopyMangaApi,\n    private val pathWord: String,\n    private val type: Int,\n) :\n    PagingSource<Int, TopicItem>() {\n\n    override fun getRefreshKey(state: PagingState<Int, TopicItem>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TopicItem> {\n        val offset = params.key ?: 0\n        return try {\n            val data = copyMangaApi.getMangaTopicList(\n                offset = offset,\n                type = type,\n                name = pathWord\n            )\n            LoadResult.Page(\n                data = data.results.list,\n                prevKey = null,\n                nextKey = if (data.results.offset >= data.results.total) null else offset + 21\n            )\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LoadResult.Error(e)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/WebHistoryPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.webhistory.WebHistoryItem\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass WebHistoryPagingSource(private val copyMangaApi: CopyMangaApi) :\n    PagingSource<Int, WebHistoryItem>() {\n\n    override fun getRefreshKey(state: PagingState<Int, WebHistoryItem>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, WebHistoryItem> {\n        val offset = params.key ?: 0\n        return try {\n            val data = copyMangaApi.browsedComics(offset = offset)\n            return LoadResult.Page(\n                data = data.results.list,\n                prevKey = null,\n                nextKey = if (data.results.offset > data.results.total) null else offset + 21\n            )\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LoadResult.Error(e)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/pagingsource/WebShelfPagingSource.kt",
    "content": "package com.shicheeng.copymanga.pagingsource\n\nimport androidx.paging.PagingSource\nimport androidx.paging.PagingState\nimport com.shicheeng.copymanga.data.webbookshelf.WebBookshelfItem\nimport com.shicheeng.copymanga.domin.CopyMangaApi\n\nclass WebShelfPagingSource(\n    private val copyMangaApi: CopyMangaApi,\n) : PagingSource<Int, WebBookshelfItem>() {\n\n    override fun getRefreshKey(state: PagingState<Int, WebBookshelfItem>): Int? {\n        return null\n    }\n\n    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, WebBookshelfItem> {\n        val offset = params.key ?: 0\n        return try {\n            val data = copyMangaApi.bookshelfWeb(offset = offset)\n            LoadResult.Page(\n                data = data.results.list,\n                prevKey = null,\n                nextKey = if (data.results.offset > data.results.total) null else offset + 21\n            )\n        } catch (e: Exception) {\n            e.printStackTrace()\n            LoadResult.Error(e)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/AuthorsMangaRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.PagingData\nimport com.shicheeng.copymanga.data.authormanga.AuthorMangaItem\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.AuthorsMangaPagingSource\nimport kotlinx.coroutines.flow.Flow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass AuthorsMangaRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi\n) {\n     fun fetchMangaByPathWord(pathWord:String): Flow<PagingData<AuthorMangaItem>> {\n         return Pager(\n             config = PagingConfig(pageSize = 1)\n         ){\n             AuthorsMangaPagingSource(pathWord, copyMangaApi)\n         }.flow\n     }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/ComicCommentRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.ComicCommentPagingSource\nimport com.shicheeng.copymanga.util.SendUIState\nimport kotlinx.coroutines.flow.flow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass ComicCommentRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    fun loadComment(uuid: String) = Pager(\n        config = PagingConfig(1)\n    ) {\n        ComicCommentPagingSource(uuid, copyMangaApi)\n    }.flow\n\n    fun push(comic: String, comment: String) = flow {\n        emit(SendUIState.Loading)\n        try {\n            val data = copyMangaApi.commentPush(comic, comment)\n            emit(SendUIState.Success(data))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            emit(SendUIState.Error(e))\n        } finally {\n            kotlinx.coroutines.delay(3000)\n            emit(SendUIState.Idle)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/LoginDetailRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.data.logininfoshort.LoginInfoShortDataModel\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.util.UIState\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.flow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass LoginDetailRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    fun detail(): Flow<UIState<LoginInfoShortDataModel>> = flow {\n        emit(UIState.Loading)\n        try {\n            val data = copyMangaApi.shortInfo()\n            emit(UIState.Success(data))\n        } catch (e: Exception) {\n            emit(UIState.Error(e))\n        }\n\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/LoginRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport android.util.Base64\nimport com.shicheeng.copymanga.dao.MangaLoginDao\nimport com.shicheeng.copymanga.data.login.LocalLoginDataModel\nimport com.shicheeng.copymanga.data.login.toLoginDataModel\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.LoginState\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.withContext\nimport java.nio.charset.Charset\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass LoginRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n    private val loginDao: MangaLoginDao,\n    private val settingPref: SettingPref,\n) {\n    suspend fun login(username: String, password: String) = flow {\n        emit(LoginState.Loading)\n        val salt = (0..Int.MAX_VALUE).random()\n        val passwordEncode = \"$password-${salt}\".toByteArray(Charset.forName(\"utf-8\"))\n        val passwordB64 = Base64.encodeToString(passwordEncode, Base64.DEFAULT)\n        try {\n            val loginDataModel =\n                copyMangaApi.login(username, passwordB64 = passwordB64, salt = salt)\n            val loginLocal = loginDataModel.toLoginDataModel(isSelected = true)\n            loginDao.updateOrInsertLoginData(loginLocal)\n            val newList = loginDao\n                .getLoginDataAsync()\n                .map { x -> x.copy(selected = x.userID == loginLocal.userID) }\n            settingPref.selectedUUId(uuid = loginLocal.userID)\n            loginDao.updateOrInsertLoginData(localLoginDataModels = newList.toTypedArray())\n            emit(LoginState.Success(loginDataModel))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            emit(LoginState.Error(e))\n        }\n    }\n\n    fun getAllLoginInstance() = loginDao.getLoginData()\n\n    fun getUserByUUid(uuid: String) = loginDao.getLoginDataByUserId(uuid)\n\n    fun deleteOneInstance(localLoginDataModel: LocalLoginDataModel) = loginDao::deleteLoginData\n\n    suspend fun selectOne(\n        uuid: String,\n    ) = withContext(Dispatchers.IO) {\n        val newList = loginDao.getLoginDataAsync().map { x ->\n            x.copy(selected = x.userID == uuid)\n        }\n        loginDao.updateOrInsertLoginData(localLoginDataModels = newList.toTypedArray())\n        settingPref.selectedUUId(uuid)\n    }\n\n    fun testLoginStatus(\n        uuid: String? = settingPref.loginPerson,\n    ) = flow {\n        val prevLoginInfo = loginDao.getLoginDataByUserIdSafety(uuid)\n        if (prevLoginInfo == null) {\n            emit(null)\n            return@flow\n        }\n        try {\n            val info = copyMangaApi.loginInfo()\n                .toLoginDataModel(\n                    localLoginDataModel = prevLoginInfo,\n                    isSelected = prevLoginInfo.selected,\n                    isExpired = false\n                )\n            loginDao.updateOrInsertLoginData(info)\n            emit(null)\n        } catch (e: Exception) {\n            val info = prevLoginInfo.copy(isExpired = true)\n            loginDao.updateOrInsertLoginData(info)\n            emit(e)\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/LoginTokenRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.dao.MangaLoginDao\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.emptyFlow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n/**\n * 防止依赖注入循环。\n */\n@Singleton\nclass LoginTokenRepository @Inject constructor(\n    private val loginDao: MangaLoginDao,\n    private val settingPref: SettingPref,\n) {\n\n    /**\n     * 登录Token，没有则返回null。\n     */\n    val token: String?\n        get() {\n            return loginDao.getCurrentToken(settingPref.loginPerson ?: return null)\n        }\n\n    val isExpired: Boolean\n        get() {\n            return loginDao.isExpired(settingPref.loginPerson ?: return true)\n        }\n\n    val isExpiredFlow:Flow<Boolean> get() {\n        return loginDao.isExpiredFlow(settingPref.loginPerson ?: return emptyFlow())\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaFilterRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport android.util.Log\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.PagingData\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.data.finished.Item\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.ExplorePagingSource\nimport com.shicheeng.copymanga.util.await\nimport com.shicheeng.copymanga.util.parserAsJson\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.withContext\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport retrofit2.Retrofit\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaFilterRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n    private val okHttpClient: OkHttpClient,\n    private val retrofit: Retrofit,\n) {\n\n    /**\n     * 需要自己手动解析\n     */\n    suspend fun theme(): List<MangaSortBean> = withContext(Dispatchers.Default) {\n        val request =\n            Request.Builder()\n                .url(\"https://\" + retrofit.baseUrl().host + \"/api/v3/h5/filterIndex/comic/tags\")\n                .build()\n        val call = okHttpClient.newCall(request).await()\n        call.body?.string()?.let {\n            buildList {\n                add(MangaSortBean(\"无\", \"\"))\n                it.parserAsJson().asJsonObject[\"results\"].asJsonObject[\"theme\"].asJsonArray.forEach {\n                    val name = it.asJsonObject[\"name\"].asString\n                    val pathWord = it.asJsonObject[\"path_word\"].asString\n                    add(MangaSortBean(name, pathWord))\n                }\n            }\n        } ?: emptyList()\n    }\n\n    fun filterMangas(\n        top: String? = null,\n        theme: String? = null,\n        ordering: String? = null,\n    ): Flow<PagingData<Item>> {\n        return Pager(\n            config = PagingConfig(pageSize = 21),\n            pagingSourceFactory = {\n                ExplorePagingSource(copyMangaApi, ordering, theme, top)\n            }\n        ).flow\n    }\n\n\n}\n\nfun Any.logD(tag: String = \"com.shihcheeng.logd\") {\n    Log.d(tag, \"$this\")\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaFinishedRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.json.MangaSortJson\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaFinishedRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    suspend fun fetchFinishManga(offset: Int) = copyMangaApi.fetchMangaFilter(\n        top = MangaSortJson.topPath.find { x -> x.pathName == \"已完结\" }?.pathWord,\n        offset = offset\n    )\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaHistoryRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.dao.MangeLocalHistoryDao\nimport com.shicheeng.copymanga.dao.SearchHistoryDao\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport com.shicheeng.copymanga.data.searchhistory.SearchHistory\nimport com.shicheeng.copymanga.util.processLifecycleScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaHistoryRepository @Inject constructor(\n    private val mangeLocalHistoryDao: MangeLocalHistoryDao,\n    private val searchedWordDao: SearchHistoryDao,\n) {\n\n    val allHistoryDao: Flow<List<MangaHistoryDataModel>> = mangeLocalHistoryDao.getAllHistory()\n\n    suspend fun totalHistoryManga() =\n        mangeLocalHistoryDao.fetchTotalManga()\n\n    suspend fun getMangaByPathWord(pathWord: String): LocalSavableMangaModel? {\n        return mangeLocalHistoryDao.getMangaByPathWord(pathWord)\n    }\n\n    suspend fun fetchMangaChapterByPathWord(pathWord: String): List<LocalChapter>? {\n        return mangeLocalHistoryDao.fetchMangaChaptersByPathWord(pathWord)\n    }\n\n    fun fetchMangaChapterByPathWordFlow(pathWord: String): Flow<List<LocalChapter>?> {\n        return mangeLocalHistoryDao.fetchMangaChaptersByPathWordFlow(pathWord)\n    }\n\n    fun fetchMangaByPathWordInFlow(pathWord: String) =\n        mangeLocalHistoryDao.fetchHistoryByPathWordInFlow(pathWord)\n\n\n    suspend fun update(mangaLocalHistory: MangaHistoryDataModel) {\n        mangeLocalHistoryDao.updateLocal(mangaLocalHistory)\n    }\n\n    /**\n     * 保存漫画历史。其生命周期不随ViewModel。\n     */\n    fun updateAsync(mangaLocalHistory: MangaHistoryDataModel) {\n        processLifecycleScope.launch(Dispatchers.IO) {\n            try {\n                mangeLocalHistoryDao.updateLocal(mangaLocalHistory)\n            } catch (e: Exception) {\n                e.printStackTrace()\n            }\n        }\n    }\n\n\n    suspend fun updateLocalChapter(localChapter: LocalChapter) {\n        mangeLocalHistoryDao.addLocalChapter(localChapter)\n    }\n\n    suspend fun updateLocalChapter(localChapter: List<LocalChapter>) {\n        mangeLocalHistoryDao.addLocalChapter(*localChapter.toTypedArray())\n    }\n\n    suspend fun getHistoryByMangaPathWord(pathWord: String): MangaHistoryDataModel? =\n        mangeLocalHistoryDao.getHistoryForInfoByPathWord(pathWord)\n\n    suspend fun delHistory() {\n        mangeLocalHistoryDao.deleteAllHistory()\n    }\n\n    suspend fun deleteSingleHistory(mangaHistoryDataModel: MangaHistoryDataModel) {\n        mangeLocalHistoryDao.deleteSingle(mangaHistoryDataModel)\n    }\n\n    fun historySearchedWord() = searchedWordDao.loadWordHistory()\n\n    suspend fun delKeyWordHistory(searchHistory: SearchHistory) =\n        searchedWordDao.detectSearchedWordHistory(searchHistory)\n\n    suspend fun upsertSearchWord(searchHistory: SearchHistory) {\n        searchedWordDao.upsertWord(searchHistory)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaHotRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.json.MangaSortJson\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaHotRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    suspend fun fetchHotMangas(offset: Int) = copyMangaApi.fetchMangaFilter(\n        ordering = MangaSortJson.order.find { x -> x.pathName == \"最热\" }?.pathWord,\n        offset = offset\n    )\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaInfoRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.data.chapter.toLocalChapter\nimport com.shicheeng.copymanga.data.info.MangaInfoDataModel\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.domin.DownloadFileDetectUtil\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.formNumberToRead\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaInfoRepository @Inject constructor(\n    private val detectUtil: DownloadFileDetectUtil,\n    private val copyMangaApi: CopyMangaApi,\n    private val mangaHistoryRepository: MangaHistoryRepository,\n    private val settingPref: SettingPref,\n) {\n\n    suspend fun fetchMangaChapters(pathWord: String): List<LocalChapter> {\n        return mangaHistoryRepository.fetchMangaChapterByPathWord(pathWord)\n            ?.takeIf { it.isNotEmpty() }\n            ?: copyMangaApi.fetchChapters(pathWord = pathWord).let {\n                it.results.list.map { remoteChapter ->\n                    remoteChapter.toLocalChapter(\n                        readIndex = 0,\n                        isReadInProgress = false,\n                        isDownloaded = detectUtil.detectChapterDownloadedByUUID(\n                            pathWord,\n                            remoteChapter.uuid\n                        ),\n                        isReadFinish = false\n                    )\n                }\n            }.also {\n                mangaHistoryRepository.updateLocalChapter(it)\n            }\n    }\n\n    suspend fun fetchMangaChaptersForce(pathWord: String): List<LocalChapter> {\n        val mangaLocalChapters = mangaHistoryRepository.fetchMangaChapterByPathWord(pathWord)\n        return copyMangaApi.fetchChapters(pathWord = pathWord).let {\n            it.results.list.map { remoteChapter ->\n                remoteChapter.toLocalChapter(\n                    readIndex = mangaLocalChapters?.find { x ->\n                        x.uuid == remoteChapter.uuid\n                    }?.readIndex ?: 0,\n                    isReadInProgress = mangaLocalChapters?.find { x ->\n                        x.uuid == remoteChapter.uuid\n                    }?.isReadProgress ?: false,\n                    isDownloaded = detectUtil.detectChapterDownloadedByUUID(\n                        pathWord,\n                        remoteChapter.uuid\n                    ),\n                    isReadFinish = mangaLocalChapters?.find { x ->\n                        x.uuid == remoteChapter.uuid\n                    }?.isReadFinish ?: false\n                )\n            }\n        }.also {\n            mangaHistoryRepository.updateLocalChapter(it)\n        }\n    }\n\n    suspend fun collect(comicId: String, isCollect: Boolean): Boolean {\n        return try {\n            copyMangaApi.comicCollect(comicId, isCollect = if (isCollect) 1 else 0)\n            true\n        } catch (e: Exception) {\n            e.printStackTrace()\n            false\n        }\n    }\n\n    suspend fun fetchMangaInfo(pathWord: String): MangaHistoryDataModel {\n        return mangaHistoryRepository.getHistoryByMangaPathWord(pathWord)\n            ?: copyMangaApi.getMangaInfo(pathWord = pathWord).toMangaLocalInfo(\n                readerMode = ReaderMode.valueOf(settingPref.readerMode)\n            ).also {\n                mangaHistoryRepository.update(it)\n            }\n    }\n\n    suspend fun fetchMangaInfoForce(pathWord: String): MangaHistoryDataModel {\n        val oldHistory = mangaHistoryRepository.getHistoryByMangaPathWord(pathWord)\n        return copyMangaApi.getMangaInfo(pathWord = pathWord).toMangaLocalInfo(\n            readerMode = ReaderMode.idOf(oldHistory?.readerModeId)\n                ?: ReaderMode.valueOf(settingPref.readerMode),\n            isSubscribe = oldHistory?.isSubscribe ?: false\n        ).also {\n            mangaHistoryRepository.update(it)\n        }\n    }\n\n\n    suspend fun fetchContent(\n        pathWord: String,\n        uuid: String,\n    ): List<MangaReaderPage> {\n        val url = copyMangaApi.fetchMangaContentPicture(pathWord, uuid).results.chapter\n        return buildList {\n            url.contents.forEachIndexed { index, c ->\n                add(\n                    MangaReaderPage(\n                        url = c.url,\n                        index = url.words[index],\n                        uuid = url.uuid\n                    )\n                )\n            }\n        }.sortedBy {\n            it.index\n        }\n    }\n\n    fun fetchComicWebHistory(pathWord: String) = flow {\n        val dataModel = copyMangaApi.comicWebHistory(pathWord)\n        emit(dataModel)\n    }\n\n    suspend fun fetchContentMayLocal(\n        localList: List<MangaReaderPage>? = null,\n        pathWord: String,\n        uuid: String,\n    ): List<MangaReaderPage> = withContext(Dispatchers.Default) {\n        if (localList != null) {\n            val sortedList = localList.sortedWith { text1, text2 ->\n                text1.url\n                    .split(\"/\")\n                    .last()\n                    .split(\"_\")\n                    .last()\n                    .split(\".\")\n                    .first()\n                    .toInt()\n                    .compareTo(\n                        text2.url\n                            .split(\"/\")\n                            .last()\n                            .split(\"_\")\n                            .last()\n                            .split(\".\")\n                            .first()\n                            .toInt()\n                    )\n            }\n            val newList = buildList {\n                for (i in sortedList.indices) {\n                    add(sortedList[i].copy(index = i))\n                }\n            }\n            newList\n        } else {\n            try {\n                val url = copyMangaApi.fetchMangaContentPicture(pathWord, uuid).results.chapter\n                buildList {\n                    url.contents.forEachIndexed { index, c ->\n                        add(\n                            MangaReaderPage(\n                                url = c.url,\n                                index = url.words[index],\n                                uuid = url.uuid\n                            )\n                        )\n                    }\n                }.sortedBy {\n                    it.index\n                }\n            } catch (e: Exception) {\n                e.printStackTrace()\n                emptyList()\n            }\n\n        }\n    }\n\n\n}\n\nfun MangaInfoDataModel.toMangaLocalInfo(\n    readerMode: ReaderMode,\n    isSubscribe: Boolean = false,\n): MangaHistoryDataModel {\n    return MangaHistoryDataModel(\n        name = results.comic.name,\n        time = System.currentTimeMillis(),\n        url = results.comic.cover,\n        pathWord = results.comic.pathWord,\n        nameChapter = results.comic.lastChapter.name,\n        positionChapter = 0,\n        positionPage = 0,\n        readerModeId = readerMode.id,\n        mangaDetail = results.comic.brief,\n        mangaLastUpdate = results.comic.datetimeUpdated ?: \"未知\",\n        mangaPopularNumber = results.popular.toLong().formNumberToRead(),\n        mangaRegion = results.comic.region.display,\n        mangaStatus = results.comic.status.display,\n        mangaStatusId = results.comic.status.value,\n        themeList = results.comic.theme.map { MangaSortBean(it.name, it.pathWord) },\n        authorList = results.comic.author,\n        alias = results.comic.alias,\n        isSubscribe = isSubscribe,\n        comicUUID = results.comic.uuid\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaMainPageRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.google.gson.JsonArray\nimport com.google.gson.JsonObject\nimport com.shicheeng.copymanga.data.DataBannerBean\nimport com.shicheeng.copymanga.data.ListBeanManga\nimport com.shicheeng.copymanga.data.MainPageDataModel\nimport com.shicheeng.copymanga.data.MainTopicDataModel\nimport com.shicheeng.copymanga.data.MangaRankMiniModel\nimport com.shicheeng.copymanga.json.MainBannerJson\nimport com.shicheeng.copymanga.util.authorNameReformation\nimport com.shicheeng.copymanga.util.formNumberToRead\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.withContext\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaMainPageRepository @Inject constructor(\n    private val mainBannerJson: MainBannerJson,\n) {\n\n    private fun fetchMainBannerData(inputJsonObject: JsonObject): List<DataBannerBean> {\n        val data = mainBannerJson.getBannerMain(inputJsonObject)\n        return buildList {\n            data.forEach {\n                val bannerBean = DataBannerBean()\n                val jsonObject1 = it.jsonObject //Banner组下面的各个jsonObject\n                bannerBean.bannerBrief = jsonObject1[\"brief\"].asString\n                bannerBean.bannerImageUrl = jsonObject1[\"cover\"].asString\n                bannerBean.uuidManga = jsonObject1[\"comic\"]\n                    .asJsonObject[\"path_word\"].asString\n                add(bannerBean)\n            }\n        }\n    }\n\n    private fun fetchMainRowData(inputJsonArray: JsonArray): List<ListBeanManga> {\n        return buildList {\n            inputJsonArray.forEach { jsonElement ->\n                //因为有第二个jsonObject，所以需要再次获取一次。\n                val jsonObject1 = jsonElement.asJsonObject.getAsJsonObject(\"comic\")\n                val nameManga = jsonObject1[\"name\"].asString\n                val urlCoverManga = jsonObject1[\"cover\"].asString\n                val pathWordManga = jsonObject1[\"path_word\"].asString\n                val mangaAuthor = jsonObject1[\"author\"].asJsonArray.takeIf { it.size() != 0 }\n                    ?.authorNameReformation() ?: \"未知\"\n                val beanManga = ListBeanManga(\n                    nameManga = nameManga,\n                    authorManga = mangaAuthor,\n                    urlCoverManga = urlCoverManga,\n                    pathWordManga = pathWordManga\n                )\n                add(beanManga)\n            }\n        }\n    }\n\n    private fun fetchMainRowData2(inputJsonArray: JsonArray): List<ListBeanManga> {\n        return buildList {\n            inputJsonArray.forEach { jsonElement ->\n                val jsonObject1 = jsonElement.asJsonObject\n                val nameManga = jsonObject1[\"name\"].asString\n                val urlCoverManga = jsonObject1[\"cover\"].asString\n                val pathWordManga = jsonObject1[\"path_word\"].asString\n                val mangaAuthorList = jsonObject1[\"author\"].asJsonArray.authorNameReformation()\n                val beanManga =\n                    ListBeanManga(nameManga, mangaAuthorList, urlCoverManga, pathWordManga)\n                add(beanManga)\n            }\n        }\n    }\n\n    private fun transformMainRecTopic(inputJsonArray: JsonArray): List<MainTopicDataModel> {\n        return inputJsonArray.map { element ->\n            element.asJsonObject.let {\n                val title = it[\"title\"].asString\n                val journal = it[\"journal\"].asString\n                val coverUrl = it[\"cover\"].asString\n                val period = it[\"period\"].asString\n                val type = it[\"type\"].asInt\n                val brief = it[\"brief\"].asString\n                val pathWord = it[\"path_word\"].asString\n                val time = it[\"datetime_created\"].asString\n                MainTopicDataModel(\n                    name = title,\n                    journal = journal,\n                    coverUrl = coverUrl,\n                    period = period,\n                    type = type,\n                    brief = brief,\n                    pathWord = pathWord,\n                    datetimeCreated = time\n                )\n            }\n        }\n    }\n\n    private fun parserJsonLeaderBoardData(array: JsonArray?): List<MangaRankMiniModel> {\n        return buildList {\n            array?.forEach { jsonElement ->\n                val comic = jsonElement.asJsonObject[\"comic\"].asJsonObject\n                val popular = comic[\"popular\"].asLong.formNumberToRead()\n                val name = comic[\"name\"].asString\n                val pathWord = comic[\"path_word\"].asString\n                val author = comic[\"author\"].asJsonArray.authorNameReformation()\n                val cover = comic[\"cover\"].asString\n                val riseNum = jsonElement.asJsonObject[\"rise_num\"].asLong.formNumberToRead()\n                val data = MangaRankMiniModel(name, author, cover, popular, riseNum, pathWord)\n                add(data)\n            }\n        }\n\n    }\n\n    /**\n     * 主页数据\n     */\n    suspend fun fetchMainData() = withContext(Dispatchers.Default) {\n        val mainData = mainBannerJson.fetchMainListData()\n        val listBanner = fetchMainBannerData(mainData)\n        val listRecommend = fetchMainRowData(mainBannerJson.getRecMain(mainData))\n        val listNewest = fetchMainRowData(mainBannerJson.getNewMain(mainData))\n        val listHot = fetchMainRowData(mainBannerJson.getHotMain(mainData))\n        val listFinished = fetchMainRowData2(mainBannerJson.getFinishMain(mainData))\n        val mapRankJsonArray = mainBannerJson.getDayRankMain(mainData)\n        val listRankWeek = parserJsonLeaderBoardData(mapRankJsonArray[1])\n        val listRankDay = parserJsonLeaderBoardData(mapRankJsonArray[0])\n        val listRankMonth = parserJsonLeaderBoardData(mapRankJsonArray[2])\n        val topic = transformMainRecTopic(mainBannerJson.getRecTopic(mainData))\n        MainPageDataModel(\n            listBanner = listBanner,\n            listRecommend = listRecommend,\n            listRankDay = listRankDay,\n            listRankWeek = listRankWeek,\n            listRankMonth = listRankMonth,\n            listHot = listHot,\n            listNewest = listNewest,\n            listFinished = listFinished,\n            topicList = topic\n        )\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaNewestRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaNewestRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    suspend fun fetchNewestMangas(offset: Int) = copyMangaApi.getMangaNewest(offset = offset)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaRankRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.PagingData\nimport com.shicheeng.copymanga.data.rank.Item\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.RankPagingSource\nimport kotlinx.coroutines.flow.Flow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaRankRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    fun fetchMangaRank(type: String): Flow<PagingData<Item>> {\n        return Pager(\n            config = PagingConfig(pageSize = 21),\n            pagingSourceFactory = {\n                RankPagingSource(copyMangaApi, type)\n            }\n        ).flow\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaRecommendRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport javax.inject.Inject\n\nclass MangaRecommendRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    suspend fun fetchRecommendMangas(offset: Int) = copyMangaApi.getMangaRecommend(offset = offset)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaSearchRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.PagingData\nimport com.shicheeng.copymanga.data.search.SearchResultDataModel\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.SearchResultPagingSource\nimport kotlinx.coroutines.flow.Flow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaSearchRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    fun fetchSearchResult(query: String): Flow<PagingData<SearchResultDataModel>> {\n        return Pager(\n            config = PagingConfig(pageSize = 21),\n            pagingSourceFactory = {\n                SearchResultPagingSource(query, copyMangaApi)\n            }\n        ).flow\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/MangaTopicDetailRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.TopicDetailListPagingSource\nimport com.shicheeng.copymanga.util.UIState\nimport kotlinx.coroutines.flow.flow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass MangaTopicDetailRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    fun load(pathWord: String) = flow {\n        emit(UIState.Loading)\n        try {\n            val data = copyMangaApi.getMangaTopicInfo(pathWord)\n            emit(UIState.Success(data))\n        } catch (e: Exception) {\n            emit(UIState.Error(e))\n        }\n    }\n\n    fun mangas(\n        pathWord: String,\n        type: Int,\n    ) = Pager(\n        config = PagingConfig(pageSize = 1)\n    ) {\n        TopicDetailListPagingSource(copyMangaApi, pathWord, type)\n    }.flow\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/WebHistoryRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.WebHistoryPagingSource\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass WebHistoryRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    fun historyOnWeb() = Pager(\n        config = PagingConfig(pageSize = 1)\n    ) {\n        WebHistoryPagingSource(copyMangaApi)\n    }.flow\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/resposity/WebShelfRepository.kt",
    "content": "package com.shicheeng.copymanga.resposity\n\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.WebShelfPagingSource\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass WebShelfRepository @Inject constructor(\n    private val copyMangaApi: CopyMangaApi,\n) {\n\n    fun loadWebShelf() = Pager(\n        pagingSourceFactory = {\n            WebShelfPagingSource(copyMangaApi)\n        },\n        config = PagingConfig(pageSize = 1)\n    ).flow\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/DownloadState.kt",
    "content": "package com.shicheeng.copymanga.server\n\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\n\nsealed interface DownloadStateChapter {\n    val chapterID: Int\n    val chapter: LocalSavableMangaModel\n\n    class WAITING(\n        override val chapterID: Int,\n        override val chapter: LocalSavableMangaModel,\n    ) : DownloadStateChapter\n\n    class PREPARE(\n        override val chapterID: Int,\n        override val chapter: LocalSavableMangaModel,\n    ) : DownloadStateChapter\n\n    class DOWNLOADING(\n        override val chapterID: Int,\n        override val chapter: LocalSavableMangaModel,\n        totalChapters: Int,\n        currentChapter: Int,\n        val totalPages: Int,\n        val currentPage: Int,\n        val currentLocalChapter: LocalChapter,\n    ) : DownloadStateChapter {\n        val max: Int = totalChapters * totalPages\n        val progress: Int = totalPages * currentChapter + currentPage + 1\n        val percent: Float = progress.toFloat() / max\n    }\n\n    class ERROR(\n        override val chapterID: Int,\n        override val chapter: LocalSavableMangaModel,\n        val error: Throwable,\n    ) : DownloadStateChapter\n\n    class DONE(\n        override val chapterID: Int,\n        override val chapter: LocalSavableMangaModel,\n    ) : DownloadStateChapter\n\n    class PostBeforeDone(\n        override val chapterID: Int,\n        override val chapter: LocalSavableMangaModel,\n    ) :\n        DownloadStateChapter\n\n    class CANCEL(override val chapterID: Int, override val chapter: LocalSavableMangaModel) :\n        DownloadStateChapter\n\n}\n\n\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/download/domin/DownloadState.kt",
    "content": "package com.shicheeng.copymanga.server.download.domin\n\nimport androidx.work.Data\nimport com.shicheeng.copymanga.data.LocalManga\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\n\ndata class DownloadState(\n    val localSavableMangaModel: LocalSavableMangaModel,\n    val error: String? = null,\n    val isStopped: Boolean = false,\n    val isPaused: Boolean = false,\n    val totalChapters: Int = 0,\n    val currentChapter: Int = 0,\n    val isIndeterminate: Boolean = false,\n    val totalPages: Int = 0,\n    val currentPage: Int = 0,\n    val localManga: LocalManga? = null,\n    val downloadedChapters: Array<String> = emptyArray(),\n    val timestamp: Long = System.currentTimeMillis(),\n    val eta: Long = -1L,\n) {\n    val max: Int = totalChapters * totalPages\n    val progress: Int = totalPages * currentChapter + currentPage + 1\n\n    val percent: Float = if (max > 0) progress.toFloat() / max else PROGRESS_NONE\n\n    val isParticularProgress: Boolean\n        get() = localManga == null && error == null && !isPaused && !isStopped && max > 0 && !isIndeterminate\n\n    val isFinalState: Boolean\n        get() = localManga != null || (error != null && !isPaused)\n\n\n    fun transformToWorkData() = Data.Builder()\n        .putInt(MANGA_MAX, max)\n        .putInt(MANGA_PROGRESS, progress)\n        .putString(MANGA_ERROR, error)\n        .putStringArray(MANGA_DOWNLOAD_CHAPTER, downloadedChapters)\n        .putLong(MANGA_TIME_STAMP, timestamp)\n        .putString(MANGA_PATH_WORD, localSavableMangaModel.mangaHistoryDataModel.pathWord)\n        .putBoolean(IS_INDETERMINATE, isIndeterminate)\n        .putBoolean(IS_STOPPED, isStopped)\n        .putBoolean(IS_PAUSE, isPaused)\n        .putLong(MANGA_ETA, eta)\n        .build()\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (javaClass != other?.javaClass) return false\n\n        other as DownloadState\n\n        if (localSavableMangaModel != other.localSavableMangaModel) return false\n        if (error != other.error) return false\n        if (totalChapters != other.totalChapters) return false\n        if (currentChapter != other.currentChapter) return false\n        if (totalPages != other.totalPages) return false\n        if (currentPage != other.currentPage) return false\n        if (!downloadedChapters.contentEquals(other.downloadedChapters)) return false\n        if (timestamp != other.timestamp) return false\n        if (isStopped != other.isStopped) return false\n        if (max != other.max) return false\n        if (progress != other.progress) return false\n        if (isPaused != other.isPaused) return false\n        if (isIndeterminate != other.isIndeterminate) return false\n        return percent == other.percent\n    }\n\n    override fun hashCode(): Int {\n        var result = localSavableMangaModel.hashCode()\n        result = 31 * result + (error?.hashCode() ?: 0)\n        result = 31 * result + totalChapters\n        result = 31 * result + currentChapter\n        result = 31 * result + totalPages\n        result = 31 * result + currentPage\n        result = 31 * result + downloadedChapters.contentHashCode()\n        result = 31 * result + timestamp.hashCode()\n        result = 31 * result + max\n        result = 31 * result + totalPages\n        result = 31 * result + percent.hashCode()\n        result = 31 * result + isIndeterminate.hashCode()\n        result = 31 * result + isPaused.hashCode()\n        result = 31 * result + isStopped.hashCode()\n        return result\n    }\n\n    companion object {\n\n        private const val PROGRESS_NONE = -1f\n        private const val MANGA_PATH_WORD = \"MangaPathWord\"\n        private const val MANGA_MAX = \"MangaMax\"\n        private const val MANGA_ETA = \"MangaEta\"\n        private const val IS_PAUSE = \"IsPause\"\n        private const val IS_STOPPED = \"IsStopped\"\n        private const val MANGA_ERROR = \"MangaError\"\n        private const val MANGA_DOWNLOAD_CHAPTER = \"MangaDownloadChapter\"\n        private const val MANGA_CURRENT = \"MangaCurrent\"\n        private const val IS_INDETERMINATE = \"IsIndeterminate\"\n        private const val MANGA_TIME_STAMP = \"MangaTimeStamp\"\n        private const val MANGA_PROGRESS = \"MangaProgress\"\n\n        infix fun getMangaPathWord(data: Data) = data.getString(MANGA_PATH_WORD)\n        infix fun getError(data: Data) = data.getString(MANGA_ERROR)\n        infix fun getMax(data: Data) = data.getInt(MANGA_MAX, 0)\n        infix fun getProgress(data: Data) = data.getInt(MANGA_PROGRESS, 0)\n        infix fun timeStampWhich(data: Data) = data.getLong(MANGA_TIME_STAMP, 0L)\n        infix fun downloadChaptersIn(data: Data): Array<String> =\n            data.getStringArray(MANGA_DOWNLOAD_CHAPTER) ?: emptyArray()\n\n        infix fun indeterminateFor(data: Data): Boolean {\n            return data.getBoolean(IS_INDETERMINATE, false)\n        }\n\n        infix fun isPauseIn(data: Data): Boolean = data.getBoolean(IS_PAUSE, false)\n        infix fun isStoppedIn(data: Data): Boolean = data.getBoolean(IS_STOPPED, false)\n        infix fun timeETAIn(data: Data) = data.getLong(MANGA_ETA, 0L)\n\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/download/domin/DownloaderLocalIndex.kt",
    "content": "package com.shicheeng.copymanga.server.download.domin\n\nimport com.google.gson.JsonObject\nimport com.google.gson.JsonParser\nimport com.shicheeng.copymanga.BuildConfig\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.data.info.Author\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport com.shicheeng.copymanga.util.add\nimport com.shicheeng.copymanga.util.toJsonArray\n\nclass DownloaderLocalIndex(source: String?) {\n\n    constructor(source: () -> String?) : this(source())\n\n    private val jsonObject = if (\n        !source.isNullOrEmpty()\n        && source.isNotEmpty()\n        && JsonParser.parseString(source).isJsonObject\n    ) {\n        JsonParser.parseString(source).asJsonObject\n    } else {\n        JsonObject()\n    }\n\n    fun setMangaData(localSavableMangaModel: LocalSavableMangaModel, append: Boolean) {\n        jsonObject.apply {\n            addProperty(\"comic_id\", localSavableMangaModel.mangaHistoryDataModel.comicUUID)\n            addProperty(\"name\", localSavableMangaModel.mangaHistoryDataModel.name)\n            addProperty(\"cover\", localSavableMangaModel.mangaHistoryDataModel.url)\n            addProperty(\"description\", localSavableMangaModel.mangaHistoryDataModel.mangaDetail)\n            addProperty(\"state\", localSavableMangaModel.mangaHistoryDataModel.mangaStatus)\n            addProperty(\"alias\", localSavableMangaModel.mangaHistoryDataModel.alias)\n            addProperty(\"last_update\", localSavableMangaModel.mangaHistoryDataModel.mangaLastUpdate)\n            addProperty(\"name_chapter\", localSavableMangaModel.mangaHistoryDataModel.nameChapter)\n            addProperty(\"path_word\", localSavableMangaModel.mangaHistoryDataModel.pathWord)\n            addProperty(\n                \"manga_popular_num\",\n                localSavableMangaModel.mangaHistoryDataModel.mangaPopularNumber\n            )\n            addProperty(\"manga_region\", localSavableMangaModel.mangaHistoryDataModel.mangaRegion)\n            addProperty(\n                \"manga_reader_int\",\n                localSavableMangaModel.mangaHistoryDataModel.readerModeId\n            )\n            addProperty(\n                \"manga_state_id\",\n                localSavableMangaModel.mangaHistoryDataModel.mangaStatusId\n            )\n            addProperty(\n                \"time\",\n                localSavableMangaModel.mangaHistoryDataModel.time\n            )\n            add(\"tags\") {\n                localSavableMangaModel.mangaHistoryDataModel.themeList.toJsonArray(\n                    header = { x -> x.pathName },\n                    values = { y -> y.pathWord },\n                    headerProperty = \"name\",\n                    valuesProperty = \"path_word\"\n                )\n            }\n            add(\"authors\") {\n                localSavableMangaModel.mangaHistoryDataModel.authorList.toJsonArray(\n                    header = { x -> x.name },\n                    headerProperty = \"name\",\n                    valuesProperty = \"path_word\",\n                    values = { y -> y.pathWord }\n                )\n            }\n            if (!append || !jsonObject.has(\"chapters\")) {\n                add(\"chapters\", JsonObject())\n            }\n            addProperty(\"app_version\", BuildConfig.VERSION_NAME)\n            addProperty(\"app_id\", BuildConfig.APPLICATION_ID)\n        }\n    }\n\n    fun getMangaData() = if (jsonObject.isEmpty) null else runCatching {\n        MangaHistoryDataModel(\n            name = jsonObject[\"name\"].asString,\n            comicUUID = jsonObject[\"comic_id\"].asString,\n            readerModeId = jsonObject[\"manga_reader_int\"].asInt,\n            mangaLastUpdate = jsonObject[\"last_update\"].asString,\n            mangaDetail = jsonObject[\"description\"].asString,\n            nameChapter = jsonObject[\"name_chapter\"].asString,\n            time = jsonObject[\"time\"].asLong,\n            alias = jsonObject[\"alias\"].asString.takeIf { it.isNotBlank() && it.isNotEmpty() },\n            pathWord = jsonObject[\"path_word\"].asString,\n            mangaPopularNumber = jsonObject[\"manga_popular_num\"].asString,\n            mangaRegion = jsonObject[\"manga_region\"].asString,\n            mangaStatus = jsonObject[\"state\"].asString,\n            mangaStatusId = jsonObject[\"manga_state_id\"].asInt,\n            themeList = jsonObject[\"tags\"].asJsonArray.map {\n                MangaSortBean(\n                    it.asJsonObject[\"name\"].asString,\n                    it.asJsonObject[\"path_word\"].asString\n                )\n            },\n            url = jsonObject[\"cover\"].asString,\n            authorList = jsonObject[\"authors\"].asJsonArray.map {\n                Author(it.asJsonObject[\"name\"].asString, it.asJsonObject[\"path_word\"].asString)\n            },\n            isSubscribe = false,\n            positionChapter = 0,\n            positionPage = 0\n        )\n    }.getOrNull()\n\n\n    fun getCoverEntry(): String? = jsonObject.has(\"cover_entry\").let {\n        if (it) jsonObject[\"cover_entry\"].asString else null\n    }\n\n    fun setCoverEntry(name: String) {\n        jsonObject.addProperty(\"cover_entry\", name)\n    }\n\n    fun addChapter(chapter: LocalChapter, fileName: String?) {\n        val jsonChapters = jsonObject[\"chapters\"].asJsonObject\n        if (!jsonChapters.has(chapter.uuid)) {\n            jsonChapters.add(chapter.uuid) {\n                JsonObject().also {\n                    it.apply {\n                        addProperty(\"chapter_name\", chapter.name)\n                        addProperty(\"comic_path_word\", chapter.comicPathWord)\n                        addProperty(\"chapter_is_reading\", chapter.isReadProgress)\n                        addProperty(\"chapter_comic_id\", chapter.comicId)\n                        addProperty(\"file_name\", fileName)\n                    }\n                }\n            }\n        }\n    }\n\n    fun removeChapters(chapter: LocalChapter): Boolean {\n        return jsonObject[\"chapters\"].asJsonObject.remove(chapter.uuid) != null\n    }\n\n    fun getChapters(\n        vararg uuid: String,\n        localSavableMangaModel: LocalSavableMangaModel,\n    ): List<LocalChapter> {\n        return localSavableMangaModel.list.filter {\n            uuid.contains(it.uuid)\n        }\n    }\n\n    fun getChapterJson(uuid: String): JsonObject? {\n        return if (jsonObject.isJsonObject && jsonObject.has(uuid)) {\n            jsonObject[uuid].asJsonObject\n        } else null\n    }\n\n    override fun toString(): String {\n        return jsonObject.toString()\n    }\n\n    companion object {\n\n        private const val OUT_PUT_FILE = \"\"\n\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/download/domin/DownloaderOutPutter.kt",
    "content": "package com.shicheeng.copymanga.server.download.domin\n\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport com.shicheeng.copymanga.fm.domain.makeDirIfNoExist\nimport com.shicheeng.copymanga.util.KeyWordSwap\nimport kotlinx.coroutines.runInterruptible\nimport java.io.File\n\nclass DownloaderOutPutter(\n    private val rootFile: File,\n    private val localSavableMangaModel: LocalSavableMangaModel,\n) {\n\n    private val rootFileDir = rootFile.makeDirIfNoExist()\n    private val downloaderIndexer = DownloaderLocalIndex {\n        File(rootFileDir, KeyWordSwap.LOCAL_SAVABLE_INDEX_JSON)\n            .also {\n                it.createNewFile()\n            }\n            .takeIf { x -> x.exists() && x.canRead() }\n            ?.readText()\n    }\n\n    init {\n        downloaderIndexer.setMangaData(localSavableMangaModel, append = true)\n    }\n\n    suspend fun addCover(file: File, ext: String) {\n        val name = buildString {\n            append(\"cover\")\n            if (ext.isNotEmpty() && ext.length < 4) {\n                append(\".\")\n                append(ext)\n            }\n        }\n        runInterruptible {\n            file.copyTo(File(rootFile, name), overwrite = true)\n        }\n        downloaderIndexer.setCoverEntry(name)\n        completedIndex()\n    }\n\n    suspend fun addPager(\n        localChapter: LocalChapter,\n        file: File,\n        pagerNumber: Int,\n        ext: String,\n    ) {\n        val name = buildString {\n            append(\"/\")\n            append(localChapter.name)\n            append(\"/\")\n            append(\"${localChapter.name}_\")\n            append(pagerNumber)\n            if (ext.isNotEmpty() && ext.length < 4) {\n                append(\".\")\n                append(ext)\n            }\n        }\n        runInterruptible {\n            file.copyTo(File(rootFile, name), overwrite = true)\n        }\n        downloaderIndexer.addChapter(localChapter, name)\n    }\n\n    fun getDownloadChapters(array: Array<String>) = downloaderIndexer.getChapters(\n        uuid = array,\n        localSavableMangaModel = localSavableMangaModel\n    )\n\n    fun createNewLocalData(uuids: Array<String>): LocalSavableMangaModel {\n        return downloaderIndexer.getMangaData()?.let {\n            LocalSavableMangaModel(it, getDownloadChapters(uuids))\n        } ?: error(\"出错\")\n    }\n\n    private suspend fun completedIndex() = runInterruptible {\n        File(rootFile, KeyWordSwap.LOCAL_SAVABLE_INDEX_JSON).writeText(downloaderIndexer.toString())\n    }\n\n    suspend fun cleanUp() {\n        completedIndex()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/download/domin/PausingHandle.kt",
    "content": "package com.shicheeng.copymanga.server.download.domin\n\nimport androidx.annotation.AnyThread\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.first\n\nclass PausingHandle {\n\n\tprivate val paused = MutableStateFlow(false)\n\n\t@get:AnyThread\n\tval isPaused: Boolean\n\t\tget() = paused.value\n\n\t@AnyThread\n\tsuspend fun awaitResumed() {\n\t\tpaused.filter { !it }.first()\n\t}\n\n\t@AnyThread\n\tfun pause() {\n\t\tpaused.value = true\n\t}\n\n\t@AnyThread\n\tfun resume() {\n\t\tpaused.value = false\n\t}\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/download/domin/PausingHandler.kt",
    "content": "package com.shicheeng.copymanga.server.download.domin\n\nimport android.content.BroadcastReceiver\nimport android.content.Context\nimport android.content.Intent\nimport android.content.IntentFilter\nimport android.net.Uri\nimport android.os.PatternMatcher\nimport androidx.core.app.PendingIntentCompat\nimport com.shicheeng.copymanga.util.transformToUUIDMayNullSafety\nimport java.util.UUID\n\nclass PausingHandler(\n    private val workerID: UUID,\n    private val pausingHandle: PausingHandle,\n) : BroadcastReceiver() {\n\n    override fun onReceive(context: Context?, intent: Intent?) {\n        val uuid = intent?.getStringExtra(UUID_STRING).transformToUUIDMayNullSafety()\n        if (uuid != workerID) return\n        when (intent?.action) {\n            ACTION_PAUSE -> pausingHandle.pause()\n            ACTION_RESUME -> pausingHandle.resume()\n        }\n    }\n\n    companion object {\n        private const val UUID_STRING = \"uuid\"\n        private const val ACTION_PAUSE = \"com.shihcheeng.copymanga.download.PAUSE\"\n        private const val ACTION_RESUME = \"com.shihcheeng.copymanga.download.RESUME\"\n        private const val SCHEME = \"workuid\"\n\n        fun createIntentFilter(id: UUID) = IntentFilter().apply {\n            addAction(ACTION_PAUSE)\n            addAction(ACTION_RESUME)\n            addDataScheme(SCHEME)\n            addDataPath(id.toString(), PatternMatcher.PATTERN_SIMPLE_GLOB)\n        }\n\n        fun getPauseIntent(context: Context, id: UUID) = Intent(ACTION_PAUSE)\n            .setData(Uri.parse(\"$SCHEME://$id\"))\n            .setPackage(context.packageName)\n            .putExtra(UUID_STRING, id.toString())\n\n        fun getResumeIntent(context: Context, id: UUID) = Intent(ACTION_RESUME)\n            .setData(Uri.parse(\"$SCHEME://$id\"))\n            .setPackage(context.packageName)\n            .putExtra(UUID_STRING, id.toString())\n\n        fun createPausePendingIntent(context: Context, id: UUID) = PendingIntentCompat.getBroadcast(\n            context,\n            0,\n            getPauseIntent(context, id),\n            0,\n            false,\n        )\n\n        fun createResumePendingIntent(context: Context, id: UUID) =\n            PendingIntentCompat.getBroadcast(\n                context,\n                0,\n                getResumeIntent(context, id),\n                0,\n                false,\n            )\n\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/download/woker/DownloadNotificationFactory.kt",
    "content": "package com.shicheeng.copymanga.server.download.woker\n\nimport android.app.Notification\nimport android.app.NotificationManager\nimport android.app.PendingIntent\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.drawable.Drawable\nimport androidx.core.app.NotificationChannelCompat\nimport androidx.core.app.NotificationCompat\nimport androidx.core.app.NotificationManagerCompat\nimport androidx.core.app.TaskStackBuilder\nimport androidx.core.graphics.drawable.toBitmap\nimport androidx.core.net.toUri\nimport androidx.work.WorkManager\nimport coil.ImageLoader\nimport coil.request.ErrorResult\nimport coil.request.ImageRequest\nimport coil.request.SuccessResult\nimport coil.size.Scale\nimport com.shicheeng.copymanga.MainActivity\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport com.shicheeng.copymanga.server.download.domin.DownloadState\nimport com.shicheeng.copymanga.server.download.domin.PausingHandler\nimport com.shicheeng.copymanga.ui.screen.Router\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport java.util.UUID\n\nprivate const val DOWNLOAD_CHANNEL_ID = \"DOWNLOAD_CHANNEL\"\n\nclass DownloadNotificationFactory @AssistedInject constructor(\n    @ApplicationContext private val context: Context,\n    private val workerManager: WorkManager,\n    private val coil: ImageLoader,\n    @Assisted uuid: UUID,\n) {\n\n    private val downloadGroupID = \"DOWNLOAD_GROUP\"\n    private val builder = NotificationCompat.Builder(context, DOWNLOAD_CHANNEL_ID)\n    private val covers = HashMap<LocalSavableMangaModel, Drawable>()\n    private val mutex = Mutex()\n    private val coverWidth = context.resources.getDimensionPixelSize(\n        androidx.core.R.dimen.compat_notification_large_icon_max_width,\n    )\n    private val coverHeight = context.resources.getDimensionPixelSize(\n        androidx.core.R.dimen.compat_notification_large_icon_max_height,\n    )\n\n    private val downloadPending = TaskStackBuilder.create(context).run {\n        addNextIntentWithParentStack(\n            Intent(\n                Intent.ACTION_VIEW,\n                Router.DOWNLOAD.deepLink.toUri(),\n                context,\n                MainActivity::class.java\n            )\n        )\n        getPendingIntent(0, PendingIntent.FLAG_MUTABLE)\n    }\n    private val actionCancel by lazy {\n        NotificationCompat.Action(\n            com.google.android.material.R.drawable.material_ic_clear_black_24dp,\n            context.getString(android.R.string.cancel),\n            workerManager.createCancelPendingIntent(uuid),\n        )\n    }\n    private val actionPause by lazy {\n        NotificationCompat.Action(\n            R.drawable.baseline_pause_24,\n            context.getString(R.string.pause),\n            PausingHandler.createPausePendingIntent(context, uuid),\n        )\n    }\n\n    private val actionResume by lazy {\n        NotificationCompat.Action(\n            R.drawable.baseline_play_arrow_24,\n            context.getString(R.string.resume),\n            PausingHandler.createResumePendingIntent(context, uuid),\n        )\n    }\n\n\n    init {\n        bindNotification()\n        builder.setSilent(true)\n        builder.setDefaults(0)\n        builder.setGroup(downloadGroupID)\n        builder.setOnlyAlertOnce(true)\n        builder.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_CHILDREN)\n        builder.foregroundServiceBehavior = NotificationCompat.FOREGROUND_SERVICE_IMMEDIATE\n        builder.setGroupSummary(true)\n        builder.setContentTitle(context.getString(R.string.downloading))\n    }\n\n    suspend fun buildNotification(state: DownloadState?): Notification = mutex.withLock {\n        if (state == null) {\n            builder.setContentText(context.getString(R.string.preparing))\n            builder.setContentTitle(context.getString(R.string.downloading))\n        } else {\n            builder.setContentTitle(state.localSavableMangaModel.mangaHistoryDataModel.name)\n            builder.setContentText(context.getString(R.string.downloading))\n        }\n        builder.setProgress(1, 0, true)\n        builder.setSmallIcon(android.R.drawable.stat_sys_download)\n        builder.setContentIntent(downloadPending)\n        builder.setStyle(null)\n        builder.setLargeIcon(if (state != null) getCover(state.localSavableMangaModel)?.toBitmap() else null)\n        builder.clearActions()\n        builder.setSubText(null)\n        builder.setShowWhen(false)\n        builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)\n        when {\n            state == null -> Unit\n            state.localManga != null -> {\n                builder.setProgress(0, 0, false)\n                builder.setContentText(context.getString(R.string.completed))\n                builder.setContentIntent(null)\n                builder.setAutoCancel(true)\n                builder.setSmallIcon(android.R.drawable.stat_sys_download_done)\n                builder.setCategory(null)\n                builder.setStyle(null)\n                builder.setOngoing(false)\n                builder.setShowWhen(true)\n                builder.setWhen(System.currentTimeMillis())\n            }\n\n            state.isStopped -> {\n                builder.setProgress(0, 0, false)\n                builder.setContentText(context.getString(R.string.waiting))\n                builder.setCategory(NotificationCompat.CATEGORY_PROGRESS)\n                builder.setStyle(null)\n                builder.setOngoing(true)\n                builder.setSmallIcon(R.drawable.ic_stat_name)\n                builder.addAction(actionCancel)\n            }\n\n            state.isPaused -> {\n                builder.setProgress(state.max, state.progress, false)\n                val percent = if (state.percent >= 0) {\n                    reformatPercentString(percent = state.percent)\n                } else {\n                    null\n                }\n                if (state.error != null) {\n                    builder.setContentText(\"$percent • ${state.error}\")\n                } else {\n                    builder.setContentText(percent)\n                }\n                builder.setCategory(NotificationCompat.CATEGORY_PROGRESS)\n                builder.setStyle(null)\n                builder.setOngoing(true)\n                builder.setSmallIcon(R.drawable.baseline_pause_24)\n                builder.addAction(actionCancel)\n                builder.addAction(actionResume)\n            }\n\n            state.error != null -> { // error, final state\n                builder.setProgress(0, 0, false)\n                builder.setSmallIcon(android.R.drawable.stat_notify_error)\n                builder.setSubText(context.getString(R.string.error))\n                builder.setContentText(state.error)\n                builder.setAutoCancel(true)\n                builder.setOngoing(false)\n                builder.setCategory(NotificationCompat.CATEGORY_ERROR)\n                builder.setShowWhen(true)\n                builder.setWhen(System.currentTimeMillis())\n                builder.setStyle(NotificationCompat.BigTextStyle().bigText(state.error))\n            }\n\n            else -> {\n                builder.setProgress(state.max, state.progress, false)\n                builder.setContentText(reformatPercentString(state.percent))\n                builder.setCategory(NotificationCompat.CATEGORY_PROGRESS)\n                builder.setStyle(null)\n                builder.setOngoing(true)\n                builder.addAction(actionCancel)\n                builder.addAction(actionPause)\n            }\n        }\n        return builder.build()\n    }\n\n    private fun reformatPercentString(percent: Float): String {\n        return \"%.2f%%\".format((percent * 100))\n    }\n\n    private suspend fun getCover(localSavableMangaModel: LocalSavableMangaModel) =\n        covers[localSavableMangaModel] ?: run {\n            runCatching {\n                coil.execute(\n                    ImageRequest.Builder(context)\n                        .data(localSavableMangaModel.mangaHistoryDataModel.url)\n                        .allowHardware(false)\n                        .tag(localSavableMangaModel.mangaHistoryDataModel.comicUUID)\n                        .size(coverWidth, coverHeight)\n                        .scale(Scale.FILL)\n                        .build()\n                ).let {\n                    when (it) {\n                        is ErrorResult -> throw it.throwable\n                        is SuccessResult -> it.drawable\n                    }\n                }\n            }.onSuccess {\n                covers[localSavableMangaModel] = it\n            }.onFailure {\n                it.printStackTrace()\n            }.getOrNull()\n        }\n\n    private fun bindNotification() {\n        val notificationManager = NotificationManagerCompat.from(context)\n        val name = context.getString(R.string.download_channel_name)\n        val importance = NotificationManager.IMPORTANCE_DEFAULT\n        val mChannel = NotificationChannelCompat.Builder(DOWNLOAD_CHANNEL_ID, importance)\n            .setName(name)\n            .setVibrationEnabled(false)\n            .setLightsEnabled(false)\n            .setSound(null, null)\n            .build()\n        notificationManager.createNotificationChannel(mChannel)\n    }\n\n    @AssistedFactory\n    interface Injket {\n        fun create(uuid: UUID): DownloadNotificationFactory\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/download/woker/DownloadedWorker.kt",
    "content": "package com.shicheeng.copymanga.server.download.woker\n\nimport android.app.NotificationManager\nimport android.content.Context\nimport android.content.pm.ServiceInfo\nimport android.os.Build\nimport android.webkit.MimeTypeMap\nimport androidx.core.content.ContextCompat\nimport androidx.hilt.work.HiltWorker\nimport androidx.lifecycle.asFlow\nimport androidx.work.BackoffPolicy\nimport androidx.work.Constraints\nimport androidx.work.CoroutineWorker\nimport androidx.work.Data\nimport androidx.work.ForegroundInfo\nimport androidx.work.NetworkType\nimport androidx.work.OneTimeWorkRequestBuilder\nimport androidx.work.OutOfQuotaPolicy\nimport androidx.work.WorkManager\nimport androidx.work.WorkerParameters\nimport androidx.work.await\nimport com.shicheeng.copymanga.data.LocalManga\nimport com.shicheeng.copymanga.domin.DownloadFileDetectUtil\nimport com.shicheeng.copymanga.fm.domain.PagerCache\nimport com.shicheeng.copymanga.fm.domain.makeDirIfNoExist\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport com.shicheeng.copymanga.resposity.MangaInfoRepository\nimport com.shicheeng.copymanga.resposity.logD\nimport com.shicheeng.copymanga.server.download.domin.DownloadState\nimport com.shicheeng.copymanga.server.download.domin.DownloaderOutPutter\nimport com.shicheeng.copymanga.server.download.domin.PausingHandle\nimport com.shicheeng.copymanga.server.download.domin.PausingHandler\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.Throttler\nimport com.shicheeng.copymanga.util.await\nimport com.shicheeng.copymanga.util.messageNoNull\nimport com.shicheeng.copymanga.util.progress.TimeLeftEstimator\nimport com.shicheeng.copymanga.util.useWithContext\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedInject\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.NonCancellable\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport kotlinx.coroutines.withContext\nimport okhttp3.OkHttpClient\nimport okhttp3.Request\nimport okio.buffer\nimport okio.sink\nimport java.io.File\nimport java.io.IOException\nimport java.util.UUID\nimport java.util.concurrent.TimeUnit\nimport javax.inject.Inject\n\n@HiltWorker\nclass DownloadedWorker @AssistedInject constructor(\n    @Assisted appContext: Context,\n    @Assisted params: WorkerParameters,\n    private val mangaHistoryRepository: MangaHistoryRepository,\n    private val pagerCache: PagerCache,\n    private val mangaInfoRepository: MangaInfoRepository,\n    private val detectUtil: DownloadFileDetectUtil,\n    private val okHttpClient: OkHttpClient,\n    downloadNotificationFactory: DownloadNotificationFactory.Injket,\n) : CoroutineWorker(appContext, params) {\n\n    private val notificationFactory = downloadNotificationFactory.create(params.id)\n    private val notificationManager = appContext.getSystemService(NotificationManager::class.java)\n    private val mutex = Mutex()\n    private val throttler = Throttler(400)\n    private val pausingHandle = PausingHandle()\n    private val pausingHandler = PausingHandler(params.id, pausingHandle)\n    private val timeLeftEstimator = TimeLeftEstimator()\n\n    @Volatile\n    private var _lastState: DownloadState? = null\n\n    private val lastState: DownloadState\n        get() = checkNotNull(_lastState)\n\n\n    override suspend fun doWork(): Result {\n        setForeground(getForegroundInfo())\n        val mangaPathWord = inputData.getString(MANGA_PATH_WORD)\n            ?: return Result.failure()\n        val manga = mangaHistoryRepository.getMangaByPathWord(mangaPathWord)\n            ?: return Result.failure()\n        val downloadedChapters = getDoneChapters()\n        val mangaDownloadUUIDs = inputData.getStringArray(MANGA_DOWNLOAD_UUIDS)\n            ?.takeUnless { it.isEmpty() }\n        _lastState = DownloadState(\n            localSavableMangaModel = manga,\n            isIndeterminate = true\n        )\n\n        return try {\n            downloadMangaImpl(\n                downloadUUID = mangaDownloadUUIDs,\n                downloadedUUID = downloadedChapters\n            )\n            Result.success()\n        } catch (e: CancellationException) {\n            withContext(NonCancellable) {\n                val notification =\n                    notificationFactory.buildNotification(lastState.copy(isStopped = true))\n                notificationManager.notify(id.hashCode(), notification)\n            }\n            throw e\n        } catch (e: IOException) {\n            e.printStackTrace()\n            Result.retry()\n        } catch (e: Exception) {\n            e.printStackTrace()\n            Result.failure(\n                lastState.copy(\n                    error = e.message,\n                ).transformToWorkData()\n            )\n        } finally {\n            notificationManager.cancel(id.hashCode())\n        }\n    }\n\n    private suspend fun downloadMangaImpl(\n        downloadUUID: Array<String>?,\n        downloadedUUID: Array<String>,\n    ) {\n        requireNotNull(downloadUUID) {\n            \"下载的章节不可以为空\"\n        }\n        val manga = lastState.localSavableMangaModel\n        val chapterToSkip = downloadedUUID.toMutableList()\n        mutex.withLock {\n            ContextCompat.registerReceiver(\n                applicationContext,\n                pausingHandler,\n                PausingHandler.createIntentFilter(id),\n                ContextCompat.RECEIVER_NOT_EXPORTED\n            )\n            val filePath = detectUtil.getRootFile(manga)\n            val tmpFile = \"${manga.mangaHistoryDataModel.name}_$id.tmp\"\n            val outPut: DownloaderOutPutter?\n            try {\n                outPut = DownloaderOutPutter(filePath, manga)\n                val coverFile = manga.mangaHistoryDataModel.url\n                downloadFile(url = coverFile, path = filePath, tmpFile = tmpFile).let {\n                    outPut.addCover(file = it, MimeTypeMap.getFileExtensionFromUrl(coverFile))\n                }\n                val chapters = manga.list.filter {\n                    downloadUUID.contains(it.uuid)\n                }\n                for ((chapterIndex, chapter) in chapters.withIndex()) {\n                    if (chapterToSkip.remove(chapter.uuid)) {\n                        pushState(\n                            lastState.copy(downloadedChapters = lastState.downloadedChapters + chapter.uuid)\n                        )\n                        continue\n                    }\n                    val pagerInfo = runDownloadPausingDetect(pausingHandle) {\n                        mangaInfoRepository.fetchContentMayLocal(\n                            localList = null,\n                            pathWord = chapter.comicPathWord,\n                            uuid = chapter.uuid\n                        )\n                    }\n                    for ((pagerIndex, pager) in pagerInfo.withIndex()) {\n                        runDownloadPausingDetect(pausingHandle) {\n                            val page = pagerCache.get(url = pager.url)\n                                ?: downloadFile(url = pager.url, path = filePath, tmpFile)\n                            outPut.addPager(\n                                localChapter = chapter,\n                                file = page,\n                                pagerNumber = pager.index,\n                                ext = MimeTypeMap.getFileExtensionFromUrl(pager.url)\n                            )\n                            pushState(\n                                lastState.copy(\n                                    totalChapters = chapters.size,\n                                    currentChapter = chapterIndex,\n                                    isIndeterminate = false,\n                                    totalPages = pagerInfo.size,\n                                    currentPage = pagerIndex\n                                )\n                            )\n                        }\n                    }\n                    pushState(\n                        lastState.copy(\n                            downloadedChapters = lastState.downloadedChapters + chapter.uuid\n                        )\n                    )\n                    mangaHistoryRepository.updateLocalChapter(\n                        chapter.copy(isDownloaded = true)\n                    )\n                }\n                pushState(\n                    lastState.copy(isIndeterminate = true)\n                )\n                val localManga = outPut.createNewLocalData(downloadUUID)\n                pushState(\n                    lastState.copy(localManga = LocalManga(localManga, filePath))\n                )\n                outPut.cleanUp()\n            } catch (e: Exception) {\n                if (e !is CancellationException) {\n                    pushState(\n                        lastState.copy(error = e.message)\n                    )\n                }\n                throw e\n            } finally {\n                withContext(NonCancellable) {\n                    applicationContext.unregisterReceiver(pausingHandler)\n                    File(filePath, tmpFile).apply {\n                        withContext(Dispatchers.IO) {\n                            delete() || deleteRecursively()\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private suspend fun downloadFile(\n        url: String,\n        path: File,\n        tmpFile: String,\n    ): File {\n        val request: Request = Request.Builder().url(url).build()\n        val call = okHttpClient.newCall(request)\n        val response = call.clone().await()\n        val file = File(path, tmpFile).also {\n            withContext(Dispatchers.IO) {\n                it.createNewFile()\n            }\n        }\n        checkNotNull(response.body).use { body ->\n            file.sink(append = false).buffer().useWithContext(Dispatchers.IO) {\n                it.writeAll(body.source())\n            }\n        }\n        return file\n    }\n\n    override suspend fun getForegroundInfo(): ForegroundInfo {\n        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n            ForegroundInfo(\n                id.hashCode(),\n                notificationFactory.buildNotification(_lastState),\n                ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC,\n            )\n        } else {\n            ForegroundInfo(\n                id.hashCode(),\n                notificationFactory.buildNotification(_lastState),\n            )\n        }\n    }\n\n    private suspend fun getDoneChapters(): Array<String> {\n        val work = WorkManager.getInstance(applicationContext).getWorkInfoById(id).await()\n            ?: return emptyArray()\n        return DownloadState downloadChaptersIn work.progress\n    }\n\n    private suspend fun pushState(state: DownloadState) {\n        val previous = lastState\n        _lastState = state\n        if (previous.isParticularProgress && state.isParticularProgress) {\n            timeLeftEstimator.tick(state.progress, state.max)\n        } else {\n            timeLeftEstimator.emptyTick()\n            throttler.reset()\n        }\n        val notification = notificationFactory.buildNotification(state)\n        if (state.isFinalState) {\n            notificationManager.notify(id.toString(), id.hashCode(), notification)\n        } else if (throttler.throttle()) {\n            notificationManager.notify(id.hashCode(), notification)\n        } else {\n            return\n        }\n        setProgress(data = state.transformToWorkData())\n    }\n\n    private suspend fun <R> runDownloadPausingDetect(\n        pausingHandle: PausingHandle,\n        block: suspend () -> R,\n    ): R {\n        if (pausingHandle.isPaused) {\n            pushState(lastState.copy(isPaused = true))\n            pausingHandle.awaitResumed()\n            pushState(lastState.copy(isPaused = false))\n        }\n        var countDown = MAX_FAILSAFE_ATTEMPTS\n        detect@ while (true) {\n            try {\n                return block()\n            } catch (e: IOException) {\n                if (countDown <= 0) {\n                    pushState(lastState.copy(isPaused = true, error = e.messageNoNull))\n                    countDown = MAX_FAILSAFE_ATTEMPTS\n                    pausingHandle.pause()\n                    pausingHandle.awaitResumed()\n                    pushState(lastState.copy(isPaused = false, error = null))\n                } else {\n                    countDown--\n                    delay(200L)\n                }\n            }\n        }\n    }\n\n\n    class Caller @Inject constructor(\n        @ApplicationContext private val context: Context,\n        private val workManager: WorkManager,\n        private val setting: SettingPref,\n    ) {\n\n        suspend fun download(pathWord: String, downloadUUIDs: Array<String>) {\n            if (downloadUUIDs.isEmpty()) return\n            val data = Data.Builder()\n                .putString(MANGA_PATH_WORD, pathWord)\n                .putStringArray(MANGA_DOWNLOAD_UUIDS, downloadUUIDs)\n                .build()\n            scheduleImpl(listOf(data))\n        }\n\n        fun observerWorker() = workManager.getWorkInfosByTagLiveData(TAG)\n            .asFlow()\n\n        suspend fun cancel(uuid: UUID) {\n            workManager.cancelWorkById(uuid).await()\n        }\n\n        private suspend fun scheduleImpl(data: Collection<Data>) {\n            if (data.isEmpty()) {\n                return\n            }\n            val constraints = createConstraints()\n            val requests = data.map { inputData ->\n                OneTimeWorkRequestBuilder<DownloadedWorker>()\n                    .setConstraints(constraints)\n                    .addTag(TAG)\n                    .keepResultsForAtLeast(30, TimeUnit.DAYS)\n                    .setBackoffCriteria(BackoffPolicy.LINEAR, 10, TimeUnit.SECONDS)\n                    .setInputData(inputData)\n                    .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)\n                    .build()\n            }\n            workManager.enqueue(requests).await()\n        }\n\n        fun pause(id: UUID) {\n            val intent = PausingHandler.getPauseIntent(context, id)\n            context.sendBroadcast(intent)\n        }\n\n        fun resume(id: UUID) {\n            val intent = PausingHandler.getResumeIntent(context, id)\n            context.sendBroadcast(intent)\n        }\n\n        suspend fun updateConstraints() {\n            val constraints = createConstraints()\n            val works = workManager.getWorkInfosByTag(TAG).await()\n            for (work in works) {\n                if (work.state.isFinished) {\n                    continue\n                }\n                val request = OneTimeWorkRequestBuilder<DownloadedWorker>()\n                    .setConstraints(constraints)\n                    .addTag(TAG)\n                    .setId(work.id)\n                    .build()\n                workManager.updateWork(request).await()\n            }\n        }\n\n        private fun createConstraints() = Constraints.Builder()\n            .setRequiredNetworkType(if (setting.downloadOnlyOnWifi) NetworkType.UNMETERED else NetworkType.CONNECTED)\n            .build()\n\n    }\n\n    companion object {\n        private const val MANGA_PATH_WORD = \"MANGA_PATH_WORD\"\n        private const val MANGA_DOWNLOAD_UUIDS = \"MANGA_DOWNLOAD_UUIDS\"\n\n        const val MAX_FAILSAFE_ATTEMPTS = 2\n        private const val TAG = \"download_worker\"\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/work/DetectMangaUpdateWork.kt",
    "content": "package com.shicheeng.copymanga.server.work\n\nimport android.app.NotificationManager\nimport android.app.PendingIntent\nimport android.content.Context\nimport android.content.Intent\nimport androidx.core.app.NotificationCompat\nimport androidx.core.app.TaskStackBuilder\nimport androidx.core.net.toUri\nimport androidx.hilt.work.HiltWorker\nimport androidx.work.Constraints\nimport androidx.work.CoroutineWorker\nimport androidx.work.ExistingPeriodicWorkPolicy\nimport androidx.work.NetworkType\nimport androidx.work.PeriodicWorkRequestBuilder\nimport androidx.work.WorkManager\nimport androidx.work.WorkerParameters\nimport com.shicheeng.copymanga.MainActivity\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport com.shicheeng.copymanga.resposity.MangaInfoRepository\nimport com.shicheeng.copymanga.ui.screen.setting.IN_BATTERY_NOT_LOW\nimport com.shicheeng.copymanga.ui.screen.setting.IN_CHARGING\nimport com.shicheeng.copymanga.ui.screen.setting.IN_WIFI\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport dagger.assisted.Assisted\nimport dagger.assisted.AssistedInject\nimport java.io.IOException\nimport java.util.concurrent.TimeUnit\n\n@HiltWorker\nclass DetectMangaUpdateWork @AssistedInject constructor(\n    @Assisted private val appContext: Context,\n    @Assisted params: WorkerParameters,\n    infoRepository: MangaInfoRepository,\n    historyRepository: MangaHistoryRepository,\n) : CoroutineWorker(appContext, params), IDetectManga.OnMangaDetectUpdate {\n\n    private val iDetectManga = IDetectManga(historyRepository, infoRepository, this)\n    private val notificationManager = appContext.getSystemService(NotificationManager::class.java)\n    private val notification =\n        NotificationCompat.Builder(appContext, DETECT_UPDATE_CHANELLE).apply {\n            setContentTitle(appContext.getString(R.string.update_manga))\n            setSmallIcon(R.drawable.ic_stat_name)\n            setContentText(appContext.getString(R.string.preparing))\n            setProgress(0, 0, true)\n            setOngoing(true)\n            setDefaults(0)\n            setGroup(GROUP_ITEM_CHAPTERS)\n            setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)\n            setGroupSummary(true)\n            setOnlyAlertOnce(true)\n            priority = NotificationCompat.PRIORITY_HIGH\n        }\n\n    override suspend fun doWork(): Result {\n        notificationManager.notify(\n            DETECT_UPDATE_NOTIFICATION_ID,\n            notification.build()\n        )\n        return try {\n            iDetectManga.fetchMangaUpdate()\n            Result.success()\n        } catch (e: IOException) {\n            e.printStackTrace()\n            Result.retry()\n        } catch (e: Exception) {\n            e.printStackTrace()\n            onError()\n            Result.failure()\n        }\n    }\n\n    override fun onReady() {\n        notificationManager.notify(\n            DETECT_UPDATE_NOTIFICATION_ID,\n            notification.build()\n        )\n    }\n\n    override fun onSubscribe(index: Int, size: Int, historyDataModel: MangaHistoryDataModel) {\n        notification.setProgress(size, index + 1, false)\n        notification.setContentText(historyDataModel.name)\n        notificationManager.notify(\n            DETECT_UPDATE_NOTIFICATION_ID,\n            notification.build()\n        )\n    }\n\n    override fun onError(\n        eIndex: Int,\n        historyDataModel: MangaHistoryDataModel,\n        exception: Throwable,\n    ) {\n        exception.printStackTrace()\n    }\n\n    override fun onSingleSuccess(\n        index: Int,\n        historyDataModel: MangaHistoryDataModel,\n        newChapter: List<LocalChapter>,\n    ) {\n        if (newChapter.isNotEmpty()) {\n            val pathWord = historyDataModel.pathWord\n            val link = \"shicheengcmdm://detail/$pathWord\"\n            val deepLinkIntent = Intent(\n                Intent.ACTION_VIEW,\n                link.toUri(),\n                appContext,\n                MainActivity::class.java\n            )\n\n            val deepLinkPendingIntent: PendingIntent? = TaskStackBuilder.create(appContext).run {\n                addNextIntentWithParentStack(deepLinkIntent)\n                getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)\n            }\n            val notificationItem = NotificationCompat\n                .Builder(appContext, DETECT_UPDATE_CHANELLE)\n                .apply {\n                    setContentTitle(historyDataModel.name)\n                    setContentText(newChapter.joinToString { it.name })\n                    setSmallIcon(R.drawable.ic_outline_page)\n                    setOngoing(false)\n                    setGroup(GROUP_ITEM_CHAPTERS)\n                    setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)\n                    setContentIntent(deepLinkPendingIntent)\n                }.build()\n            notificationManager.notify(historyDataModel.hashCode(), notificationItem)\n        }\n    }\n\n    override fun onSuccess() {\n        notification.setProgress(0, 0, false)\n        notification.setContentText(appContext.getString(R.string.completed))\n        notification.setOngoing(false)\n        notification.setAutoCancel(true)\n        notificationManager.notify(\n            DETECT_UPDATE_NOTIFICATION_ID,\n            notification.build()\n        )\n    }\n\n\n    private fun onError() {\n        notification.setProgress(0, 0, false)\n        notification.setContentText(appContext.getString(R.string.fatal_error))\n        notification.setOngoing(false)\n        notification.setAutoCancel(true)\n        notificationManager.notify(\n            DETECT_UPDATE_NOTIFICATION_ID,\n            notification.build()\n        )\n    }\n\n\n    companion object {\n        const val DETECT_UPDATE_CHANELLE = \"DETECT_UPDATE_CHANELLE\"\n        private const val DETECT_UPDATE_NOTIFICATION_ID = 0x1a2f3c\n        private const val GROUP_ITEM_CHAPTERS = \"GROUP_ITEM_CHAPTERS\"\n        private const val Tag = \"Manga Update Task\"\n\n        /**\n         * 启动这个Worker\n         */\n        fun readyToStart(\n            isEnable: Boolean,\n            context: Context,\n            settingPref: SettingPref,\n            takeInterval: Int? = null,\n        ) {\n            if (isEnable) {\n                val interval = takeInterval ?: settingPref.timeInterval.value\n                if (interval > 0) {\n                    val constraintsSetting = settingPref.updateConstant.value\n                    val constraints = Constraints.Builder()\n                        .setRequiresCharging(IN_CHARGING in constraintsSetting)\n                        .setRequiredNetworkType(\n                            if (IN_WIFI in constraintsSetting) NetworkType.UNMETERED else NetworkType.CONNECTED\n                        )\n                        .setRequiresBatteryNotLow(IN_BATTERY_NOT_LOW in constraintsSetting)\n                        .build()\n                    val work = PeriodicWorkRequestBuilder<DetectMangaUpdateWork>(\n                        repeatInterval = interval.toLong(),\n                        repeatIntervalTimeUnit = TimeUnit.HOURS,\n                        flexTimeInterval = 10,\n                        flexTimeIntervalUnit = TimeUnit.MINUTES\n                    )\n                        .addTag(Tag)\n                        .setConstraints(constraints)\n                        .build()\n                    WorkManager.getInstance(context).enqueueUniquePeriodicWork(\n                        Tag,\n                        ExistingPeriodicWorkPolicy.CANCEL_AND_REENQUEUE,\n                        work\n                    )\n                }\n            } else {\n                WorkManager.getInstance(context).cancelAllWorkByTag(Tag)\n            }\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/server/work/IDetectManga.kt",
    "content": "package com.shicheeng.copymanga.server.work\n\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport com.shicheeng.copymanga.resposity.MangaInfoRepository\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\n\nclass IDetectManga(\n    private val repository: MangaHistoryRepository,\n    private val infoRepository: MangaInfoRepository,\n    private val onMangaDetectUpdate: OnMangaDetectUpdate,\n) {\n\n    private val mutex = Mutex()\n\n    suspend fun fetchMangaUpdate() {\n        onMangaDetectUpdate.onReady()\n        val totalMangas = repository.totalHistoryManga().filter { it.isSubscribe }\n            totalMangas.forEachIndexed { index, mangaHistoryDataModel ->\n                mutex.withLock {\n                try {\n                    onMangaDetectUpdate.onSubscribe(\n                        index = index,\n                        size = totalMangas.size,\n                        historyDataModel = mangaHistoryDataModel\n                    )\n                    val oldList = repository\n                        .fetchMangaChapterByPathWord(mangaHistoryDataModel.pathWord)\n                    val list = infoRepository\n                        .fetchMangaChaptersForce(mangaHistoryDataModel.pathWord)\n                    oldList?.let {\n                        val newChapter = list.filterNot { y ->\n                            it.any { x -> x.uuid == y.uuid }\n                        }\n                        onMangaDetectUpdate.onSingleSuccess(\n                            index = index,\n                            historyDataModel = mangaHistoryDataModel,\n                            newChapter = newChapter\n                        )\n                    }\n                } catch (e: Exception) {\n                    onMangaDetectUpdate.onError(index, mangaHistoryDataModel, e)\n                }\n            }\n        }\n        onMangaDetectUpdate.onSuccess()\n    }\n\n    interface OnMangaDetectUpdate {\n        fun onReady()\n        fun onSubscribe(index: Int, size: Int, historyDataModel: MangaHistoryDataModel)\n        fun onError(eIndex: Int, historyDataModel: MangaHistoryDataModel, exception: Throwable)\n        fun onSingleSuccess(\n            index: Int,\n            historyDataModel: MangaHistoryDataModel,\n            newChapter: List<LocalChapter>,\n        )\n\n        fun onSuccess()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/MainNavigation.kt",
    "content": "package com.shicheeng.copymanga.ui.screen\n\nimport androidx.compose.runtime.Composable\nimport androidx.navigation.NavHostController\nimport androidx.navigation.NavType\nimport androidx.navigation.compose.NavHost\nimport androidx.navigation.compose.composable\nimport androidx.navigation.compose.rememberNavController\nimport androidx.navigation.navArgument\nimport androidx.navigation.navDeepLink\nimport com.shicheeng.copymanga.ui.screen.Router.COMMENT.toCommentScreen\nimport com.shicheeng.copymanga.ui.screen.Router.EXPLORE.toExplore\nimport com.shicheeng.copymanga.ui.screen.Router.HISTORY.toHistory\nimport com.shicheeng.copymanga.ui.screen.authorsmanga.AuthorsMangaScreen\nimport com.shicheeng.copymanga.ui.screen.comment.CommentScreen\nimport com.shicheeng.copymanga.ui.screen.download.DownloadScreen\nimport com.shicheeng.copymanga.ui.screen.downloaded.DownloadedScreen\nimport com.shicheeng.copymanga.ui.screen.history.HistoryScreen\nimport com.shicheeng.copymanga.ui.screen.list.NewestScreen\nimport com.shicheeng.copymanga.ui.screen.list.RecommendScreen\nimport com.shicheeng.copymanga.ui.screen.login.LoginScreen\nimport com.shicheeng.copymanga.ui.screen.login.loginlist.LoginPersonalListScreen\nimport com.shicheeng.copymanga.ui.screen.main.MainScreen\nimport com.shicheeng.copymanga.ui.screen.main.explore.ExploreScreen\nimport com.shicheeng.copymanga.ui.screen.main.home.search.SearchScreen\nimport com.shicheeng.copymanga.ui.screen.main.personal.personaldetail.PersonalDetail\nimport com.shicheeng.copymanga.ui.screen.main.subscribe.SubScribeScreen\nimport com.shicheeng.copymanga.ui.screen.manga.MangaDetailScreen\nimport com.shicheeng.copymanga.ui.screen.search.SearchResultScreen\nimport com.shicheeng.copymanga.ui.screen.setting.SettingScreen\nimport com.shicheeng.copymanga.ui.screen.setting.about.AboutScreen\nimport com.shicheeng.copymanga.ui.screen.setting.worker.WorkerScreen\nimport com.shicheeng.copymanga.ui.screen.topiclist.TopicListScreen\nimport com.shicheeng.copymanga.ui.screen.topics.TopicsScreen\nimport com.shicheeng.copymanga.ui.screen.webshelf.WebShelfScreen\nimport soup.compose.material.motion.animation.materialSharedAxisXIn\nimport soup.compose.material.motion.animation.materialSharedAxisXOut\nimport soup.compose.material.motion.animation.rememberSlideDistance\n\n\n@Composable\nfun MainComposeNavigation(\n    navController: NavHostController = rememberNavController(),\n) {\n    val slide = rememberSlideDistance()\n    NavHost(\n        navController = navController,\n        startDestination = Router.MAIN.name,\n        enterTransition = {\n            materialSharedAxisXIn(\n                forward = true,\n                slideDistance = slide\n            )\n        },\n        exitTransition = {\n            materialSharedAxisXOut(\n                forward = true,\n                slideDistance = slide\n            )\n        },\n        popEnterTransition = {\n            materialSharedAxisXIn(\n                forward = false,\n                slideDistance = slide\n            )\n        },\n        popExitTransition = {\n            materialSharedAxisXOut(\n                forward = false,\n                slideDistance = slide\n            )\n        }\n    ) {\n        composable(\n            route = Router.MAIN.name,\n        ) {\n            MainScreen(\n                onUUid = { navController.navigate(\"${Router.DETAIL.name}/$it\") },\n                onDownloadedBtnClick = {\n                    navController.navigate(Router.DOWNLOADED.name)\n                },\n                onSearchButtonClick = {\n                    navController.navigate(Router.SEARCH.name)\n                },\n                onSettingButtonClick = { navController.navigate(Router.SETTING.name) },\n                onRecommendHeaderLineClick = {\n                    navController.navigate(Router.RECOMMEND.name)\n                },\n                onNewestHeaderLineClick = {\n                    navController.navigate(Router.NEWEST.name)\n                },\n                onSubscribedClick = {\n                    navController.navigate(Router.SUBSCRIBE.name)\n                },\n                onHistoryClick = {\n                    navController.toHistory()\n                },\n                onLibraryClick = {\n                    navController.navigate(Router.WebSHELF.name)\n                },\n                onPersonalHeaderClick = { login ->\n                    if (login) {\n                        navController.navigate(Router.UserShortDETAIL.name)\n                    } else {\n                        navController.navigate(Router.LOGIN.name)\n                    }\n                },\n                onTopicClick = { pathWord, type ->\n                    navController.navigate(Router.TopicDETAIL.pathWord(pathWord, type))\n                },\n                onTopicHeaderLineClick = {\n                    navController.navigate(Router.TOPICS.name)\n                },\n                onFinishHeaderLineClick = {\n                    navController.toExplore(\n                        theme = null,\n                        top = \"finish\",\n                        order = null,\n                    )\n                },\n                onLoginExpireClick = {\n                    navController.navigate(Router.LOGIN.name)\n                }\n            ) {\n                navController.toExplore(\n                    theme = null,\n                    top = null,\n                    order = \"-popular\",\n                )\n            }\n        }\n\n        composable(\n            route = \"${Router.EXPLORE.name}?theme={theme}&top={top}&order={order}\",\n            arguments = listOf(\n                navArgument(name = \"theme\") { nullable = true },\n                navArgument(name = \"top\") { nullable = true },\n                navArgument(name = \"order\") { nullable = true }\n            )\n        ) { backStackEntry ->\n            ExploreScreen(\n                top = backStackEntry.arguments?.getString(\"top\"),\n                theme = backStackEntry.arguments?.getString(\"theme\"),\n                order = backStackEntry.arguments?.getString(\"order\"),\n                onNavigationIconClick = {\n                    navController.popBackStack()\n                }\n            ) {\n                navController.navigate(\"${Router.DETAIL.name}/${it.pathWord}\")\n            }\n        }\n\n        composable(route = Router.RECOMMEND.name) {\n            RecommendScreen(\n                onBack = {\n                    navController.popBackStack()\n                }\n            ) {\n                navController.navigate(\"${Router.DETAIL.name}/$it\")\n            }\n        }\n\n        composable(route = Router.NEWEST.name) {\n            NewestScreen(\n                onBack = {\n                    navController.popBackStack()\n                }\n            ) {\n                navController.navigate(\"${Router.DETAIL.name}/$it\")\n            }\n        }\n\n        composable(route = Router.SEARCH.name) {\n            SearchScreen(\n                onSearch = {\n                    if (it.isNotEmpty() && it.isNotBlank()) {\n                        navController.navigate(\"${Router.SearchResult.name}/$it\")\n                    }\n                }\n            ) {\n                navController.popBackStack()\n            }\n        }\n\n        composable(\n            route = \"${Router.SearchResult.name}/{searchWord}\"\n        ) { navBackStackEntry ->\n            val word = navBackStackEntry.arguments?.getString(\"searchWord\")\n            SearchResultScreen(\n                searchWord = word,\n                onNavigation = {\n                    navController.popBackStack()\n                },\n                onItemClick = {\n                    navController.navigate(\"${Router.DETAIL.name}/${it.pathWord}\")\n                }\n            )\n        }\n\n        composable(\n            route = \"${Router.DETAIL.name}/{path_word}\",\n            deepLinks = listOf(\n                navDeepLink { uriPattern = Router.DETAIL.deepLink },\n                navDeepLink { uriPattern = Router.DETAIL.copyMangaWebURl }\n            )\n        ) { backStackEntry ->\n            val pathWord = backStackEntry.arguments?.getString(\"path_word\")\n            MangaDetailScreen(\n                pathWord = pathWord,\n                onTagsClick = {\n                    navController.toExplore(\n                        top = null,\n                        order = null,\n                        theme = it.pathWord\n                    )\n                },\n                onAuthorClick = {\n                    navController.navigate(\"${Router.AuthorsMANGA.name}/${it}\")\n                },\n                onCommentClick = {\n                    navController toCommentScreen it\n                }\n            ) {\n                navController.popBackStack()\n            }\n        }\n\n        composable(\n            route = Router.SETTING.name\n        ) {\n            SettingScreen(\n                onNavigateClick = {\n                    navController.popBackStack()\n                },\n                onDownloadClick = {\n                    navController.navigate(Router.DOWNLOAD.name)\n                },\n                onWorkerClick = {\n                    navController.navigate(Router.WORKER.name)\n                },\n                onUserClick = {\n                    navController.navigate(Router.LoginSelect.name)\n                }\n            ) {\n                navController.navigate(Router.ABOUT.name)\n            }\n        }\n\n        composable(\n            route = Router.DOWNLOAD.name,\n            deepLinks = listOf(\n                navDeepLink { uriPattern = Router.DOWNLOAD.deepLink }\n            )\n        ) {\n            DownloadScreen(\n                onNavigationClick = navController::popBackStack,\n                onCardClick = {\n                    navController.navigate(\"${Router.DETAIL.name}/$it\")\n                }\n            )\n        }\n\n        composable(\n            route = Router.ABOUT.name\n        ) {\n            AboutScreen {\n                navController.popBackStack()\n            }\n        }\n\n        composable(\n            route = Router.WORKER.name\n        ) {\n            WorkerScreen {\n                navController.popBackStack()\n            }\n        }\n\n        composable(route = Router.DOWNLOADED.name) {\n            DownloadedScreen(\n                onNavigate = {\n                    navController.popBackStack()\n                }\n            ) { pathWord ->\n                if (pathWord != null) {\n                    navController.navigate(\"${Router.DETAIL.name}/$pathWord\")\n                }\n            }\n        }\n\n        composable(route = Router.HISTORY.name) {\n            HistoryScreen(\n                navigationClick = {\n                    navController.popBackStack()\n                },\n                onRequestLogin = {\n                    navController.navigate(Router.LOGIN.name)\n                }\n            ) { pathWord ->\n                navController.navigate(\"${Router.DETAIL.name}/$pathWord\")\n            }\n        }\n\n        composable(route = Router.SUBSCRIBE.name) {\n            SubScribeScreen(\n                navClick = {\n                    navController.popBackStack()\n                }\n            ) { pathWord ->\n                navController.navigate(\"${Router.DETAIL.name}/$pathWord\")\n            }\n        }\n\n        composable(\n            route = \"${Router.TopicDETAIL.name}/{pathWord}?type={type}\",\n            arguments = listOf(\n                navArgument(name = \"pathWord\") { type = NavType.StringType },\n                navArgument(name = \"type\") { type = NavType.IntType }\n            )\n        ) {\n            TopicsScreen(\n                onBack = {\n                    navController.popBackStack()\n                }\n            ) {\n                navController.navigate(\"${Router.DETAIL.name}/${it}\")\n            }\n        }\n\n        composable(\n            route = Router.TOPICS.name,\n        ) {\n            TopicListScreen(\n                onBack = { navController.popBackStack() }\n            ) {\n                navController.navigate(Router.TopicDETAIL.pathWord(it.pathWord, it.type))\n            }\n        }\n\n        composable(route = Router.LOGIN.name) {\n            LoginScreen(\n                onNavClick = {\n                    navController.popBackStack()\n                }\n            ) {\n                navController.popBackStack()\n            }\n        }\n\n        composable(route = Router.LoginSelect.name) {\n            LoginPersonalListScreen(\n                onAddClicked = {\n                    navController.navigate(Router.LOGIN.name)\n                }\n            ) {\n                navController.popBackStack()\n            }\n        }\n\n        composable(route = Router.WebSHELF.name) {\n            WebShelfScreen(\n                navClick = {\n                    navController.popBackStack()\n                },\n                reLoginClick = {\n                    navController.navigate(Router.LOGIN.name)\n                }\n            ) {\n                navController.navigate(\"${Router.DETAIL.name}/${it}\")\n            }\n        }\n\n        composable(route = Router.UserShortDETAIL.name) {\n            PersonalDetail(\n                onReLogin = {\n                    navController.navigate(Router.LOGIN.name)\n                }\n            ) {\n                navController.popBackStack()\n            }\n        }\n\n        composable(\n            route = Router.AuthorsMANGA.name + \"/{author_path_word}\",\n            arguments = listOf(\n                navArgument(name = \"author_path_word\") {\n                    nullable = true\n                    type = NavType.StringType\n                }\n            )\n        ) {\n            AuthorsMangaScreen(\n                onNav = {\n                    navController.popBackStack()\n                }\n            ) {\n                navController.navigate(\"${Router.DETAIL.name}/${it}\")\n            }\n        }\n\n        composable(route = Router.COMMENT.name + \"/{uuid_comic}\") {\n            CommentScreen(\n                navClick = navController::popBackStack\n            )\n        }\n\n    }\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/Router.kt",
    "content": "package com.shicheeng.copymanga.ui.screen\n\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.StringRes\nimport androidx.navigation.NavHostController\nimport com.shicheeng.copymanga.R\n\n/**\n * 导航路由\n * @param name 必传参数，名字。\n * @param stringId 非必传参数，适用于导航栏的字串符资源ID。\n * @param drawableRes 非必传参数，适用于导航栏的图标资源ID。\n * @param onClickIcon 非必传参数，但是如果传入[drawableRes]则必传，否则报错。在导航栏按钮被按下时显示的图标。\n */\nsealed class Router(\n    val name: String,\n    @StringRes val stringId: Int? = null,\n    @DrawableRes val drawableRes: Int? = null,\n    @DrawableRes val onClickIcon: Int? = null,\n) {\n\n    object MAIN : Router(\n        name = \"MAIN\"\n    )\n\n    object HOME : Router(\n        name = \"HOME\",\n        stringId = R.string.home_des,\n        drawableRes = R.drawable.outline_home_24,\n        onClickIcon = R.drawable.ic_baseline_home_24\n    )\n\n    object LEADERBOARD : Router(\n        name = \"LEADERBOARD\",\n        stringId = R.string.comic_rank,\n        drawableRes = R.drawable.baseline_insert_chart_outlined_24,\n        onClickIcon = R.drawable.baseline_insert_chart_24\n    )\n\n    object EXPLORE : Router(\n        name = \"EXPLORE\",\n        stringId = R.string.explore,\n        drawableRes = R.drawable.ic_explore_outline,\n        onClickIcon = R.drawable.baseline_explore_24\n    ) {\n        /**\n         * 转到[EXPLORE]界面。\n         *\n         * @param top 话题\n         * @param theme 主题\n         * @param order 排序\n         */\n        fun NavHostController.toExplore(top: String?, theme: String?, order: String?) {\n            navigate(name + \"?theme=${theme}&top=${top}&order=${order}\")\n        }\n    }\n\n    object SUBSCRIBE : Router(name = \"SUBSCRIBE\")\n\n    object HISTORY : Router(name = \"HISTORY\") {\n        fun NavHostController.toHistory() {\n            navigate(name)\n        }\n    }\n\n    object PERSONAL : Router(\n        name = \"PERSONAL\",\n        stringId = R.string.personal,\n        drawableRes = R.drawable.ic_person_center,\n        onClickIcon = R.drawable.baseline_person_24\n    )\n\n    object DOWNLOADED : Router(\n        name = \"DOWNLOADED\"\n    )\n\n    object RECOMMEND : Router(name = \"RECOMMEND\")\n\n    object NEWEST : Router(name = \"NEWEST\")\n\n    object DETAIL : Router(name = \"DETAIL\") {\n        const val deepLink = \"shicheengcmdm://detail/{path_word}\"\n        const val copyMangaWebURl = \"https://copymanga.site/h5/details/comic/{path_word}\"\n    }\n\n    object SEARCH : Router(name = \"SEARCH\")\n\n    object SearchResult : Router(name = \"SearchResult\")\n\n    object SETTING : Router(name = \"SETTING\")\n\n    object WORKER : Router(name = \"WORKER\")\n\n    object DOWNLOAD : Router(name = \"DOWNLOAD\") {\n        const val deepLink = \"shicheengcmdm://download\"\n    }\n\n    object ABOUT : Router(name = \"ABOUT\")\n\n    object TOPICS : Router(name = \"TOPIC\")\n\n    object TopicDETAIL : Router(\"TOPIC_DETAIL\") {\n        fun pathWord(pathWord: String, type: Int): String {\n            return this.name + \"/${pathWord}?type=$type\"\n        }\n    }\n\n    object LOGIN : Router(\"LOGIN\")\n\n    object LoginSelect : Router(\"LoginSelect\")\n\n    object WebSHELF : Router(\"WebSHELF\")\n\n    object UserShortDETAIL : Router(\"UserShortDETAIL\")\n\n    object AuthorsMANGA : Router(\"AuthorsMANGA\")\n\n    object COMMENT : Router(\"COMMENT\") {\n        private fun comicUUid(uuid: String): String {\n            return this.name + \"/$uuid\"\n        }\n\n        infix fun NavHostController.toCommentScreen(uuid: String) {\n            navigate(comicUUid(uuid))\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/authorsmanga/AuthorsMangaScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.authorsmanga\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.ui.screen.list.CommonListItem\nimport com.shicheeng.copymanga.util.copyComposable\nimport com.shicheeng.copymanga.viewmodel.AuthorMangaViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun AuthorsMangaScreen(\n    viewModel: AuthorMangaViewModel = hiltViewModel(),\n    onNav: () -> Unit,\n    onPathWord: (String) -> Unit,\n) {\n    val data = viewModel.list.collectAsLazyPagingItems()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(id = R.string.authors_manga))\n                },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onNav\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n        LazyVerticalGrid(\n            contentPadding = paddingValues.copyComposable(\n                start = 16.dp,\n                end = 16.dp\n            ),\n            verticalArrangement = Arrangement.spacedBy(16.dp),\n            columns = GridCells.Fixed(3),\n            horizontalArrangement = Arrangement.spacedBy(16.dp)\n        ) {\n            items(data.itemCount) { index ->\n                data[index]?.let { mangaItem ->\n                    CommonListItem(\n                        url = mangaItem.cover,\n                        title = mangaItem.name,\n                        author = mangaItem.author.joinToString { it.name }\n                    ) {\n                        onPathWord(mangaItem.pathWord)\n                    }\n                }\n            }\n            pagingLoadingIndication(\n                loadState = data.loadState.append,\n                onTry = data::retry\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/comment/CommentItem.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.comment\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedCard\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.data.mangacomment.MangaCommentListItem\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun CommentItem(\n    commentListItem: MangaCommentListItem,\n    onClick: () -> Unit,\n) {\n\n    OutlinedCard(\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(horizontal = 16.dp),\n        onClick = {\n            onClick()\n        }\n    ) {\n        Column(\n            modifier = Modifier.padding(16.dp)\n        ) {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                AsyncImage(\n                    model = commentListItem.userAvatar,\n                    contentDescription = null,\n                    modifier = Modifier\n                        .padding(8.dp)\n                        .size(32.dp)\n                        .clip(CircleShape),\n                    contentScale = ContentScale.Crop\n                )\n                Column(\n                    modifier = Modifier.padding(bottom = 4.dp),\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    Text(\n                        text = commentListItem.userName,\n                        style = MaterialTheme.typography.titleMedium\n                    )\n                    Text(\n                        text = commentListItem.createAt,\n                        style = MaterialTheme.typography.bodyMedium,\n                        color = MaterialTheme.colorScheme.onSurfaceVariant\n                    )\n                }\n            }\n            HorizontalDivider()\n            Text(\n                text = commentListItem.comment,\n                style = MaterialTheme.typography.bodyMedium,\n                modifier = Modifier.padding(vertical = 8.dp)\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/comment/CommentScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.comment\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.ime\nimport androidx.compose.foundation.layout.statusBars\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.LoadState\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.EmptyDataScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.ui.screen.compoents.pullrefresh.SwipeRefresh\nimport com.shicheeng.copymanga.ui.screen.compoents.pullrefresh.rememberSwipeRefreshState\nimport com.shicheeng.copymanga.util.SendUIState\nimport com.shicheeng.copymanga.viewmodel.CommentViewModel\n\n@OptIn(\n    ExperimentalMaterial3Api::class\n)\n@Composable\nfun CommentScreen(\n    viewModel: CommentViewModel = hiltViewModel(),\n    navClick: () -> Unit,\n) {\n\n    val list = viewModel.comments.collectAsLazyPagingItems()\n    val pullRefreshState = rememberSwipeRefreshState(\n        isRefreshing = list.loadState.refresh is LoadState.Loading,\n    )\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val (sendContent, onSendContent) = rememberSaveable { mutableStateOf(\"\") }\n    val commentStatus by viewModel.commentPush.collectAsState()\n    val isExpired by viewModel.loginIsExpired.collectAsState()\n\n    LaunchedEffect(key1 = commentStatus) {\n        if (commentStatus is SendUIState.Success) {\n            list.refresh()\n        }\n    }\n\n    Scaffold(\n        modifier = Modifier\n            .fillMaxSize()\n            .windowInsetsPadding(WindowInsets.ime),\n        topBar = {\n            TopAppBar(\n                title = { Text(text = stringResource(R.string.comic_comment_title)) },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = navClick\n                    )\n                },\n                scrollBehavior = topAppBarScrollBehavior,\n                modifier = Modifier,\n                windowInsets = WindowInsets.statusBars\n            )\n        },\n        bottomBar = {\n            CommentSendBar(\n                value = sendContent,\n                onValueChange = onSendContent,\n                sendUIState = commentStatus,\n                modifier = Modifier,\n                isExpired = isExpired\n            ) {\n                viewModel.sendComment(sendContent)\n            }\n        }\n    ) { padding ->\n        SwipeRefresh(\n            state = pullRefreshState,\n            onRefresh = {\n                list.refresh()\n            },\n            indicatorPadding = padding,\n        ) {\n            EmptyDataScreen(\n                isEmpty = list.itemSnapshotList.isEmpty(),\n                modifier = Modifier\n            ) {\n                LazyColumn(\n                    contentPadding = padding,\n                    verticalArrangement = Arrangement.spacedBy(16.dp),\n                    modifier = Modifier\n                        .fillMaxSize()\n                        .nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n                ) {\n                    items(list.itemCount) {\n                        list[it]?.let { commentItem ->\n                            CommentItem(commentListItem = commentItem) {\n\n                            }\n                        }\n                    }\n                    pagingLoadingIndication(\n                        loadState = list.loadState.append,\n                        onTry = list::retry\n                    )\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/comment/CommentSendBar.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.comment\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.animateContentSize\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.imePadding\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.foundation.text.BasicTextField\nimport androidx.compose.material3.ButtonDefaults\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.commentpush.CommentPushDataModel\nimport com.shicheeng.copymanga.ui.theme.ElevationTokens\nimport com.shicheeng.copymanga.util.SendUIState\nimport soup.compose.material.motion.animation.materialFadeThroughIn\nimport soup.compose.material.motion.animation.materialFadeThroughOut\n\n@Composable\nfun CommentSendBar(\n    modifier: Modifier = Modifier,\n    value: String,\n    isExpired:Boolean,\n    onValueChange: (String) -> Unit,\n    sendUIState: SendUIState<out CommentPushDataModel>,\n    onSend: () -> Unit,\n) {\n    Surface(\n        tonalElevation = ElevationTokens.Level4,\n        shadowElevation = ElevationTokens.Level2,\n        modifier = modifier\n            .zIndex(1f)\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(\n                    bottom = 8.dp,\n                    top = 8.dp,\n                    end = 16.dp,\n                    start = 16.dp\n                )\n                .navigationBarsPadding()\n                .imePadding()\n                .animateContentSize()\n        ) {\n            Text(\n                text = stringResource(R.string.send_comment_bar_title),\n                style = MaterialTheme.typography.titleMedium,\n                modifier = Modifier.padding(bottom = 8.dp)\n            )\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Start,\n                modifier = Modifier\n            ) {\n                BasicTextField(\n                    value = value,\n                    onValueChange = onValueChange,\n                    modifier = Modifier\n                        .weight(1f)\n                        .defaultMinSize(\n                            minWidth = ButtonDefaults.MinWidth,\n                            minHeight = ButtonDefaults.MinHeight\n                        ),\n                    textStyle = MaterialTheme.typography.bodyMedium\n                        .copy(\n                            color = MaterialTheme.colorScheme.onSurface\n                        )\n                ) {\n                    Surface(\n                        shape = CircleShape,\n                        color = MaterialTheme.colorScheme.secondaryContainer,\n                        tonalElevation = ElevationTokens.Level0,\n                        contentColor = MaterialTheme.colorScheme.onSecondaryContainer,\n                    ) {\n                        Box(\n                            modifier = Modifier.padding(\n                                horizontal = 16.dp,\n                                vertical = 8.dp\n                            ),\n                            contentAlignment = Alignment.CenterStart,\n                        ) {\n                            it()\n                            this@Row.AnimatedVisibility(\n                                visible = value.isEmpty(),\n                                enter = materialFadeThroughIn(),\n                                exit = materialFadeThroughOut()\n                            ) {\n                                Text(\n                                    text = stringResource(R.string.type_send_content),\n                                    color = MaterialTheme.colorScheme.onSurfaceVariant,\n                                    style = MaterialTheme.typography.bodyMedium\n                                )\n                            }\n                        }\n                    }\n                }\n                Spacer(modifier = Modifier.width(8.dp))\n                FilledTonalButton(\n                    onClick = onSend,\n                    enabled = sendUIState == SendUIState.Idle && !isExpired\n                ) {\n                    when (sendUIState) {\n\n                        is SendUIState.Error -> {\n                            Icon(\n                                painter = painterResource(id = R.drawable.baseline_close_24),\n                                contentDescription = null\n                            )\n                        }\n\n                        SendUIState.Idle -> {\n                            Icon(\n                                painter = painterResource(id = R.drawable.baseline_send_24),\n                                contentDescription = null\n                            )\n                        }\n\n                        SendUIState.Loading -> {\n                            CircularProgressIndicator(modifier = Modifier.size(24.dp))\n                        }\n\n                        is SendUIState.Success -> {\n                            Icon(\n                                painter = painterResource(id = R.drawable.ic_done_all),\n                                contentDescription = null\n                            )\n                        }\n                    }\n\n                    Spacer(modifier = Modifier.width(4.dp))\n                    Text(text = stringResource(R.string.send_comment))\n                }\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/CircleLoadingButton.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.theme.ElevationTokens\n\n@Composable\nfun CircleLoadingButton(\n    modifier: Modifier = Modifier,\n    isLoading: Boolean,\n    onClick: () -> Unit,\n    tonalElevation: Dp = ElevationTokens.Level3,\n) {\n    Surface(\n        onClick = onClick,\n        shape = CircleShape,\n        modifier = modifier.size(68.dp),\n        tonalElevation = tonalElevation\n    ) {\n        AnimatedContent(\n            targetState = isLoading,\n            label = \"circle loading\"\n        ) {\n            if (it) {\n                CircularProgressIndicator(\n                    modifier = Modifier.padding(16.dp)\n                )\n            } else {\n                Icon(\n                    painter = painterResource(id = R.drawable.undraw_arrow),\n                    contentDescription = stringResource(id = R.string.login_text),\n                    modifier = Modifier.padding(16.dp)\n                )\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/Components.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.StringRes\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TooltipBox\nimport androidx.compose.material3.TooltipDefaults\nimport androidx.compose.material3.rememberTooltipState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\n\n/**\n * 带有[PlainTooltipBox]的[IconButton]。\n * @param id String的资源ID,\n * @param drawableRes 图片的资源id,\n * @param onButtonClick 点击事件回调。\n */\n@Composable\n@OptIn(ExperimentalMaterial3Api::class)\nfun PlainButton(\n    modifier: Modifier = Modifier,\n    @StringRes id: () -> Int,\n    @DrawableRes drawableRes: () -> Int,\n    onButtonClick: () -> Unit,\n) {\n\n    TooltipBox(\n        tooltip = {\n            NormalTooltip(text = stringResource(id = id()))\n        },\n        modifier = modifier,\n        positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),\n        state = rememberTooltipState()\n    ) {\n        IconButton(\n            onClick = onButtonClick,\n            modifier = Modifier\n        ) {\n            Icon(\n                painter = painterResource(id = drawableRes()),\n                contentDescription = stringResource(id = id())\n            )\n        }\n    }\n\n}\n\n/**\n * 带有[PlainTooltipBox]的[IconButton]。\n * @param id String的资源ID,\n * @param drawableRes 图片的资源id,\n * @param onButtonClick 点击事件回调。\n */\n@Composable\nfun PlainButton(\n    @StringRes id: Int,\n    @DrawableRes drawableRes: Int,\n    onButtonClick: () -> Unit,\n) {\n    PlainButton(id = { id }, drawableRes = { drawableRes }, onButtonClick = onButtonClick)\n}\n\n@Composable\nprivate fun NormalTooltip(\n    modifier: Modifier = Modifier,\n    text: String,\n) {\n    Surface(\n        contentColor = MaterialTheme.colorScheme.tertiaryContainer,\n        color = MaterialTheme.colorScheme.onTertiaryContainer,\n        shape = MaterialTheme.shapes.extraSmall,\n        modifier = modifier\n    ) {\n        Text(\n            text = text,\n            style = MaterialTheme.typography.titleSmall\n                .copy(fontWeight = FontWeight.Bold),\n            modifier = Modifier.padding(8.dp)\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/ComposeExt.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport android.util.TypedValue\nimport androidx.annotation.AttrRes\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.FastOutLinearInEasing\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.spring\nimport androidx.compose.material3.ColorScheme\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.TopAppBarState\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.ReadOnlyComposable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.lerp\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.dimensionResource\nimport androidx.compose.ui.unit.Dp\nimport com.shicheeng.copymanga.ui.theme.ElevationTokens\n\n/**\n * 从Attr中引入资源\n * @param attrResId 资源ID。\n */\n@Composable\n@ReadOnlyComposable\ninternal fun dimensionAttribute(\n    @AttrRes attrResId: Int,\n) = dimensionResource(TypedValue().apply {\n    LocalContext.current.theme.resolveAttribute(\n        attrResId,\n        this,\n        true\n    )\n}.resourceId)\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun withAppBarColor(\n    backgroundColor: Color = MaterialTheme.colorScheme.surface,\n    topAppBarState: TopAppBarState,\n): Color {\n    val colorTransitionFraction = topAppBarState.overlappedFraction\n    val fraction = if (colorTransitionFraction > 0.01f) 1f else 0f\n    val appBarContainerColor by animateColorAsState(\n        targetValue = lerp(\n            start = backgroundColor,\n            stop = MaterialTheme.colorScheme.applyTonalElevation(\n                backgroundColor = backgroundColor,\n                elevation = ElevationTokens.Level2\n            ),\n            fraction = FastOutLinearInEasing.transform(fraction)\n        ),\n        animationSpec = spring(stiffness = Spring.StiffnessMediumLow), label = \"color\"\n    )\n    return appBarContainerColor\n}\n\n\nfun ColorScheme.applyTonalElevation(backgroundColor: Color, elevation: Dp): Color {\n    return if (backgroundColor == surface) {\n        surfaceColorAtElevation(elevation)\n    } else {\n        backgroundColor\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/EasyCover.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport coil.compose.AsyncImage\n\n\n@Composable\nfun CommonCover(\n    url: String,\n    contentDescription: String,\n    shape: Shape = MaterialTheme.shapes.medium,\n) {\n    AsyncImage(\n        model = url,\n        contentDescription = contentDescription,\n        placeholder = ColorPainter(MaterialTheme.colorScheme.primary),\n        modifier = Modifier\n            .aspectRatio(2f / 3f)\n            .clip(shape),\n        contentScale = ContentScale.Crop\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/EmptyDataScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport com.shicheeng.copymanga.R\n\n@Composable\nfun EmptyDataScreen(\n    modifier: Modifier = Modifier,\n    tipText: String = stringResource(id = R.string.no_content),\n    isEmpty: Boolean,\n    content: @Composable () -> Unit,\n) {\n    Box(\n        modifier = modifier\n            .fillMaxSize(),\n    ) {\n        if (isEmpty) {\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Image(\n                        painter = painterResource(id = R.drawable.undraw_no_data_re_kwbl),\n                        contentDescription = null,\n                    )\n                    Text(text = tipText)\n                }\n            }\n        } else {\n            content()\n        }\n    }\n}\n\n@Composable\nfun EmptyDataScreen(\n    modifier: Modifier = Modifier,\n    tipText: String = stringResource(id = R.string.no_content),\n) {\n\n    Box(\n        modifier = modifier.fillMaxSize(),\n        contentAlignment = Alignment.Center\n    ) {\n        Column(\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Image(\n                painter = painterResource(id = R.drawable.undraw_no_data_re_kwbl),\n                contentDescription = null,\n            )\n            Text(text = tipText)\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/LoadingScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.foundation.lazy.grid.GridItemSpan\nimport androidx.compose.foundation.lazy.grid.LazyGridScope\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.paging.LoadState\nimport com.shicheeng.copymanga.R\n\n@Composable\nfun LoadingScreen() {\n    Box(\n        modifier = Modifier.fillMaxSize(),\n        contentAlignment = Alignment.Center\n    ) {\n        CircularProgressIndicator()\n    }\n}\n\n@Composable\nfun ErrorScreen(\n    errorMessage: String,\n    onTry: () -> Unit,\n) {\n    Box(\n        modifier = Modifier.fillMaxSize(),\n        contentAlignment = Alignment.Center\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(all = 16.dp)\n                .fillMaxWidth(),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Text(text = errorMessage)\n            FilledTonalButton(onClick = onTry) {\n                Text(text = stringResource(id = R.string.retry))\n            }\n        }\n    }\n}\n\n@Composable\nfun ErrorScreen(\n    errorMessage: String,\n    onTry: () -> Unit,\n    secondaryText: String,\n    onSecondaryClick: () -> Unit = { },\n) {\n    Box(\n        modifier = Modifier.fillMaxSize(),\n        contentAlignment = Alignment.Center\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(all = 16.dp)\n                .fillMaxWidth(),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Text(text = errorMessage)\n            Spacer(modifier = Modifier.height(4.dp))\n            Row {\n                FilledTonalButton(onClick = onTry) {\n                    Text(text = stringResource(id = R.string.retry))\n                }\n                FilledTonalButton(\n                    onClick = onSecondaryClick,\n                    modifier = Modifier.padding(start = 8.dp)\n                ) {\n                    Text(text = secondaryText)\n                }\n            }\n        }\n    }\n}\n\n@Composable\nfun ErrorScreen(\n    errorMessage: String,\n    onTry: () -> Unit,\n    needSecondaryText: Boolean,\n    secondaryText: String,\n    onSecondaryClick: () -> Unit = { },\n) {\n    Box(\n        modifier = Modifier.fillMaxSize(),\n        contentAlignment = Alignment.Center\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(all = 16.dp)\n                .fillMaxWidth(),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Text(text = errorMessage)\n            Spacer(modifier = Modifier.height(4.dp))\n            Row {\n                FilledTonalButton(onClick = onTry) {\n                    Text(text = stringResource(id = R.string.retry))\n                }\n                if (needSecondaryText) {\n                    FilledTonalButton(\n                        onClick = onSecondaryClick,\n                        modifier = Modifier.padding(start = 8.dp)\n                    ) {\n                        Text(text = secondaryText)\n                    }\n                }\n            }\n        }\n    }\n}\n\nfun LazyGridScope.pagingLoadingIndication(loadState: LoadState, onTry: () -> Unit) {\n    item(\n        span = {\n            GridItemSpan(3)\n        }\n    ) {\n        when (loadState) {\n            is LoadState.Loading -> {\n                Box(\n                    modifier = Modifier.fillMaxWidth(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    CircularProgressIndicator(modifier = Modifier.padding(16.dp))\n                }\n            }\n\n            is LoadState.NotLoading -> {\n                Box(\n                    modifier = Modifier.fillMaxWidth(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Text(\n                        text = stringResource(id = R.string.all_clear),\n                        modifier = Modifier.padding(16.dp)\n                    )\n                }\n            }\n\n            is LoadState.Error -> {\n                Box(\n                    modifier = Modifier.fillMaxWidth(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Column(\n                        modifier = Modifier\n                            .padding(all = 16.dp)\n                            .fillMaxWidth(),\n                        horizontalAlignment = Alignment.CenterHorizontally\n                    ) {\n                        Text(text = stringResource(id = R.string.load_failure))\n                        FilledTonalButton(onClick = onTry) {\n                            Text(text = stringResource(id = R.string.retry))\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nfun LazyListScope.pagingLoadingIndication(loadState: LoadState, onTry: () -> Unit) {\n    item(\n        contentType = \"pagingLoadingIndication\",\n        key = \"pagingLoadingIndication\"\n    ) {\n        when (loadState) {\n            is LoadState.Loading -> {\n                Box(\n                    modifier = Modifier.fillMaxWidth(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    CircularProgressIndicator(modifier = Modifier.padding(16.dp))\n                }\n            }\n\n            is LoadState.NotLoading -> {\n                Box(\n                    modifier = Modifier.fillMaxWidth(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Text(\n                        text = stringResource(id = R.string.all_clear),\n                        modifier = Modifier.padding(16.dp)\n                    )\n                }\n            }\n\n            is LoadState.Error -> {\n                Box(\n                    modifier = Modifier.fillMaxWidth(),\n                    contentAlignment = Alignment.Center\n                ) {\n                    Column(\n                        modifier = Modifier\n                            .padding(all = 16.dp)\n                            .fillMaxWidth(),\n                        horizontalAlignment = Alignment.CenterHorizontally\n                    ) {\n                        Text(text = stringResource(id = R.string.load_failure))\n                        FilledTonalButton(onClick = onTry) {\n                            Text(text = stringResource(id = R.string.retry))\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/MangaCover.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\n\nenum class MangaCover(val size: Dp) {\n    /**\n     * 最小的封面，大小为65dp\n     */\n    ExtraSmall(65.dp),\n\n    /**\n     * 小的封面，大小为100dp\n     */\n    Small(100.dp),\n\n    /**\n     * 大的封面，大小为160dp\n     */\n    Big(160.dp);\n\n    @Composable\n    operator fun invoke(\n        url: Any?,\n        shape: Shape? = MaterialTheme.shapes.extraSmall,\n    ) {\n        AsyncImage(\n            model = url,\n            contentDescription = null,\n            contentScale = ContentScale.Crop,\n            modifier = Modifier\n                .width(size)\n                .aspectRatio(2f / 3f)\n                .then(\n                    if (shape != null) {\n                        Modifier.clip(shape)\n                    } else {\n                        Modifier\n                    }\n                ),\n            placeholder = ColorPainter(MaterialTheme.colorScheme.outline)\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/RefreshLayout.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.material.pullrefresh.PullRefreshIndicator\nimport androidx.compose.material.pullrefresh.PullRefreshState\nimport androidx.compose.material.pullrefresh.pullRefresh\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.Dp\n\n@OptIn(ExperimentalMaterialApi::class)\n@Composable\nfun RefreshLayout(\n    modifier: Modifier = Modifier,\n    pullRefreshState: PullRefreshState,\n    isRefreshing: Boolean,\n    topPadding: Dp,\n    content: @Composable () -> Unit,\n) {\n    Box(\n        modifier = modifier\n            .pullRefresh(state = pullRefreshState)\n            .fillMaxSize()\n    ) {\n        content()\n        PullRefreshIndicator(\n            refreshing = isRefreshing,\n            state = pullRefreshState,\n            contentColor = MaterialTheme.colorScheme.primary,\n            modifier = Modifier\n                .padding(top = topPadding)\n                .align(Alignment.TopCenter)\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/SaveStatePager.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.PagerScope\nimport androidx.compose.foundation.pager.PagerState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.saveable.SaveableStateHolder\nimport androidx.compose.ui.Modifier\nimport soup.compose.material.motion.animation.materialFadeThroughIn\nimport soup.compose.material.motion.animation.materialFadeThroughOut\n\nprivate const val TabFadeDuration = 200\n\n/**\n * 可以保存状态的[HorizontalPager]，实际上是一个封装。\n *\n * @param pageContent 内容\n * @param savableStateHolder 将状态提升到主界面\n * @see HorizontalPager\n */\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\nfun SaveStatePager(\n    modifier: Modifier = Modifier,\n    pagerState: PagerState,\n    contentPadding: PaddingValues,\n    savableStateHolder: SaveableStateHolder,\n    keys: (() -> List<Any>)? = null,\n    pageContent: @Composable (PagerScope.(Int) -> Unit),\n) {\n    HorizontalPager(\n        state = pagerState,\n        modifier = modifier,\n        contentPadding = contentPadding,\n        userScrollEnabled = false\n    ) {\n        savableStateHolder.SaveableStateProvider(\n            key = if (keys != null) keys()[it].hashCode() else it,\n            content = {\n                pageContent(it)\n            }\n        )\n    }\n}\n\n/**\n * A content which can switchable and have animation named [materialFadeThroughIn] and [materialFadeThroughOut].\n *\n * @param contentPadding A [PaddingValues] that use in content.\n * @param currentPager A number which pager now showing.\n * @param savableStateHolder Provide a [SaveableStateHolder] that will use in this function.\n * @param keys Provide a key list. It will use [currentPager] if null.\n * @param pageContent Content showing on screen.\n */\n@Composable\nfun SaveStateContentPager(\n    modifier: Modifier = Modifier,\n    contentPadding: PaddingValues,\n    currentPager: Int,\n    savableStateHolder: SaveableStateHolder,\n    keys: (() -> List<Any>)? = null,\n    pageContent: @Composable (Int) -> Unit,\n) {\n    AnimatedContent(\n        modifier = modifier.padding(contentPadding),\n        targetState = currentPager,\n        transitionSpec = {\n            materialFadeThroughIn(\n                initialScale = 1f,\n                durationMillis = TabFadeDuration\n            ) togetherWith materialFadeThroughOut(\n                durationMillis = TabFadeDuration\n            )\n        },\n        label = \"pager_content_move_with_material_fade\"\n    ) {\n        savableStateHolder.SaveableStateProvider(\n            key = if (keys != null) keys()[it].hashCode() else it,\n            content = {\n                pageContent(it)\n            }\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/VerticalFastScroller.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.compoents\n\nimport android.view.ViewConfiguration\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.draggable\nimport androidx.compose.foundation.gestures.rememberDraggableState\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsDraggedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyListItemInfo\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.foundation.systemGestureExclusion\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.SubcomposeLayout\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.dp\nimport kotlinx.coroutines.channels.BufferOverflow\nimport kotlinx.coroutines.flow.MutableSharedFlow\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlin.math.abs\nimport kotlin.math.max\nimport kotlin.math.min\nimport kotlin.math.roundToInt\n\n@Composable\nfun VerticalFastScroller(\n    listState: LazyListState,\n    thumbColor: Color = MaterialTheme.colorScheme.primary,\n    topContentPadding: Dp = Dp.Hairline,\n    endContentPadding: Dp = Dp.Hairline,\n    content: @Composable () -> Unit,\n) {\n\n    SubcomposeLayout { constraints ->\n\n        val contentPlaceable = subcompose(\"content\", content).map { it.measure(constraints) }\n        val contentHeight = contentPlaceable.maxByOrNull { it.height }?.height ?: 0\n        val contentWidth = contentPlaceable.maxByOrNull { it.width }?.width ?: 0\n\n        val scrollerPlaceable = subcompose(\"scroller\") {\n            val layoutInfo = listState.layoutInfo\n            val showScroller = layoutInfo.visibleItemsInfo.size < layoutInfo.totalItemsCount\n            if (!showScroller) return@subcompose\n\n            val thumbTopPadding = with(LocalDensity.current) { topContentPadding.toPx() }\n            var thumbOffsetY by remember(thumbTopPadding) { mutableFloatStateOf(thumbTopPadding) }\n\n            val dragInteractionSource = remember { MutableInteractionSource() }\n            val isThumbDragged by dragInteractionSource.collectIsDraggedAsState()\n\n\n            val heightPx =\n                contentHeight.toFloat() - thumbTopPadding - listState.layoutInfo.afterContentPadding\n            val thumbHeightPx = with(LocalDensity.current) { _thumbLength.toPx() }\n            val trackHeightPx = heightPx - thumbHeightPx\n\n            val scrolled = remember {\n                MutableSharedFlow<Unit>(\n                    extraBufferCapacity = 1,\n                    onBufferOverflow = BufferOverflow.DROP_OLDEST,\n                )\n            }\n\n            // When list scrolled\n            LaunchedEffect(listState.firstVisibleItemScrollOffset) {\n                if (listState.layoutInfo.totalItemsCount == 0 || isThumbDragged) return@LaunchedEffect\n                val scrollOffset = computeScrollOffset(state = listState)\n                val scrollRange = computeScrollRange(state = listState)\n                val proportion = scrollOffset.toFloat() / (scrollRange.toFloat() - heightPx)\n                thumbOffsetY = trackHeightPx * proportion + thumbTopPadding\n                scrolled.tryEmit(Unit)\n            }\n\n            // When thumb dragged\n            LaunchedEffect(thumbOffsetY) {\n                if (layoutInfo.totalItemsCount == 0 || !isThumbDragged) return@LaunchedEffect\n                val scrollRatio = (thumbOffsetY - thumbTopPadding) / trackHeightPx\n                val scrollItem = layoutInfo.totalItemsCount * scrollRatio\n                val scrollItemRounded = scrollItem.roundToInt()\n                val scrollItemSize =\n                    layoutInfo.visibleItemsInfo.find { it.index == scrollItemRounded }?.size ?: 0\n                val scrollItemOffset = scrollItemSize * (scrollItem - scrollItemRounded)\n                listState.scrollToItem(\n                    index = scrollItemRounded,\n                    scrollOffset = scrollItemOffset.roundToInt()\n                )\n                scrolled.tryEmit(Unit)\n            }\n\n            // Thumb alpha\n            val alpha = remember { Animatable(0f) }\n            val isThumbVisible = alpha.value > 0f\n            LaunchedEffect(scrolled, alpha) {\n                scrolled.collectLatest {\n                    alpha.snapTo(1f)\n                    alpha.animateTo(0f, animationSpec = _fadeOutAnimationSpec)\n                }\n            }\n\n            Box(\n                modifier = Modifier\n                    .offset { IntOffset(0, thumbOffsetY.roundToInt()) }\n                    .height(_thumbLength)\n                    .then(\n                        // Exclude thumb from gesture area only when needed\n                        if (isThumbVisible && !isThumbDragged && !listState.isScrollInProgress) {\n                            Modifier.systemGestureExclusion()\n                        } else Modifier,\n                    )\n                    .padding(end = endContentPadding)\n                    .width(_thumbThickness)\n                    .alpha(alpha = alpha.value)\n                    .background(color = thumbColor, shape = _thumbShape)\n                    .then(\n                        // Recompose opts\n                        if (!listState.isScrollInProgress) {\n                            Modifier.draggable(\n                                interactionSource = dragInteractionSource,\n                                orientation = Orientation.Vertical,\n                                enabled = isThumbVisible,\n                                state = rememberDraggableState { delta ->\n                                    val newOffsetY = thumbOffsetY + delta\n                                    thumbOffsetY = newOffsetY.coerceIn(\n                                        thumbTopPadding,\n                                        thumbTopPadding + trackHeightPx\n                                    )\n                                },\n                            )\n                        } else Modifier,\n                    ),\n            )\n        }.map { it.measure(constraints.copy(minWidth = 0, minHeight = 0)) }\n        val scrollerWidth = scrollerPlaceable.maxByOrNull { it.width }?.width ?: 0\n\n        layout(contentWidth, contentHeight) {\n            contentPlaceable.forEach {\n                it.placeRelative(0, 0)\n            }\n            scrollerPlaceable.forEach {\n                it.placeRelative(contentWidth - scrollerWidth, 0)\n            }\n        }\n    }\n}\n\nprivate fun computeScrollOffset(state: LazyListState): Int {\n    if (state.layoutInfo.totalItemsCount == 0) return 0\n    val visibleItems = state.layoutInfo.visibleItemsInfo\n    val startChild = visibleItems.first()\n    val endChild = visibleItems.last()\n    val minPosition = min(startChild.index, endChild.index)\n    val maxPosition = max(startChild.index, endChild.index)\n    val itemsBefore = minPosition.coerceAtLeast(0)\n    val startDecoratedTop = startChild.top\n    val laidOutArea = abs(endChild.bottom - startDecoratedTop)\n    val itemRange = abs(minPosition - maxPosition) + 1\n    val avgSizePerRow = laidOutArea.toFloat() / itemRange\n    return (itemsBefore * avgSizePerRow + (0 - startDecoratedTop)).roundToInt()\n}\n\nprivate fun computeScrollRange(state: LazyListState): Int {\n    if (state.layoutInfo.totalItemsCount == 0) return 0\n    val visibleItems = state.layoutInfo.visibleItemsInfo\n    val startChild = visibleItems.first()\n    val endChild = visibleItems.last()\n    val laidOutArea = endChild.bottom - startChild.top\n    val laidOutRange = abs(startChild.index - endChild.index) + 1\n    return (laidOutArea.toFloat() / laidOutRange * state.layoutInfo.totalItemsCount).roundToInt()\n}\n\nprivate val _thumbLength = 52.dp\nprivate val _thumbThickness = 8.dp\nprivate val _thumbShape = RoundedCornerShape(_thumbThickness / 2)\nprivate val _fadeOutAnimationSpec = tween<Float>(\n    durationMillis = ViewConfiguration.getScrollBarFadeDuration(),\n    delayMillis = 2000,\n)\n\nprivate val LazyListItemInfo.top: Int\n    get() = offset\n\nprivate val LazyListItemInfo.bottom: Int\n    get() = offset + size\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/pullrefresh/CircularProgressPainter.kt",
    "content": "/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.shicheeng.copymanga.ui.screen.compoents.pullrefresh\n\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.geometry.center\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathFillType\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.rotate\nimport androidx.compose.ui.graphics.painter.Painter\nimport androidx.compose.ui.unit.dp\nimport kotlin.math.min\n\n/**\n * A private class to do all the drawing of SwipeRefreshIndicator, which includes progress spinner\n * and the arrow. This class is to separate drawing from animation.\n * Adapted from CircularProgressDrawable.\n */\ninternal class CircularProgressPainter : Painter() {\n    var color by mutableStateOf(Color.Unspecified)\n    var alpha by mutableFloatStateOf(1f)\n    var arcRadius by mutableStateOf(0.dp)\n    var strokeWidth by mutableStateOf(5.dp)\n    var arrowEnabled by mutableStateOf(false)\n    var arrowWidth by mutableStateOf(0.dp)\n    var arrowHeight by mutableStateOf(0.dp)\n    var arrowScale by mutableFloatStateOf(1f)\n\n    private val arrow: Path by lazy {\n        Path().apply { fillType = PathFillType.EvenOdd }\n    }\n\n    var startTrim by mutableFloatStateOf(0f)\n    var endTrim by mutableFloatStateOf(0f)\n    var rotation by mutableFloatStateOf(0f)\n\n    override val intrinsicSize: Size\n        get() = Size.Unspecified\n\n    override fun applyAlpha(alpha: Float): Boolean {\n        this.alpha = alpha\n        return true\n    }\n\n    override fun DrawScope.onDraw() {\n        rotate(degrees = rotation) {\n            val arcRadius = arcRadius.toPx() + strokeWidth.toPx() / 2f\n            val arcBounds = Rect(\n                size.center.x - arcRadius,\n                size.center.y - arcRadius,\n                size.center.x + arcRadius,\n                size.center.y + arcRadius\n            )\n            val startAngle = (startTrim + rotation) * 360\n            val endAngle = (endTrim + rotation) * 360\n            val sweepAngle = endAngle - startAngle\n            drawArc(\n                color = color,\n                alpha = alpha,\n                startAngle = startAngle,\n                sweepAngle = sweepAngle,\n                useCenter = false,\n                topLeft = arcBounds.topLeft,\n                size = arcBounds.size,\n                style = Stroke(\n                    width = strokeWidth.toPx(),\n                    cap = StrokeCap.Square\n                )\n            )\n            if (arrowEnabled) {\n                drawArrow(startAngle, sweepAngle, arcBounds)\n            }\n        }\n    }\n\n    private fun DrawScope.drawArrow(startAngle: Float, sweepAngle: Float, bounds: Rect) {\n        arrow.reset()\n        arrow.moveTo(0f, 0f)\n        arrow.lineTo(\n            x = arrowWidth.toPx() * arrowScale,\n            y = 0f\n        )\n        arrow.lineTo(\n            x = arrowWidth.toPx() * arrowScale / 2,\n            y = arrowHeight.toPx() * arrowScale\n        )\n        val radius = min(bounds.width, bounds.height) / 2f\n        val inset = arrowWidth.toPx() * arrowScale / 2f\n        arrow.translate(\n            Offset(\n                x = radius + bounds.center.x - inset,\n                y = bounds.center.y + strokeWidth.toPx() / 2f\n            )\n        )\n        arrow.close()\n        rotate(degrees = startAngle + sweepAngle) {\n            drawPath(\n                path = arrow,\n                color = color,\n                alpha = alpha\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/pullrefresh/Slingshot.kt",
    "content": "/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage com.shicheeng.copymanga.ui.screen.compoents.pullrefresh\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport kotlin.math.abs\nimport kotlin.math.max\nimport kotlin.math.min\nimport kotlin.math.pow\n\n/**\n * A utility function that calculates various aspects of 'slingshot' behavior.\n * Adapted from SwipeRefreshLayout#moveSpinner method.\n *\n * TODO: Investigate replacing this with a spring.\n *\n * @param offsetY The current y offset.\n * @param maxOffsetY The max y offset.\n * @param height The height of the item to slingshot.\n */\n@Composable\ninternal fun rememberUpdatedSlingshot(\n    offsetY: Float,\n    maxOffsetY: Float,\n    height: Int,\n): Slingshot {\n    val offsetPercent = min(1f, offsetY / maxOffsetY)\n    val adjustedPercent = max(offsetPercent - 0.4f, 0f) * 5 / 3\n    val extraOffset = abs(offsetY) - maxOffsetY\n\n    // Can accommodate custom start and slingshot distance here\n    val tensionSlingshotPercent = max(\n        0f, min(extraOffset, maxOffsetY * 2) / maxOffsetY\n    )\n    val tensionPercent = (\n            (tensionSlingshotPercent / 4) -\n                    (tensionSlingshotPercent / 4).pow(2)\n            ) * 2\n    val extraMove = maxOffsetY * tensionPercent * 2\n    val targetY = height + ((maxOffsetY * offsetPercent) + extraMove).toInt()\n    val offset = targetY - height\n    val strokeStart = adjustedPercent * 0.8f\n\n    val startTrim = 0f\n    val endTrim = strokeStart.coerceAtMost(MaxProgressArc)\n\n    val rotation = (-0.25f + 0.4f * adjustedPercent + tensionPercent * 2) * 0.5f\n    val arrowScale = min(1f, adjustedPercent)\n\n    return remember { Slingshot() }.apply {\n        this.offset = offset\n        this.startTrim = startTrim\n        this.endTrim = endTrim\n        this.rotation = rotation\n        this.arrowScale = arrowScale\n    }\n}\n\n@Stable\ninternal class Slingshot {\n    var offset: Int by mutableIntStateOf(0)\n    var startTrim: Float by mutableFloatStateOf(0f)\n    var endTrim: Float by mutableFloatStateOf(0f)\n    var rotation: Float by mutableFloatStateOf(0f)\n    var arrowScale: Float by mutableFloatStateOf(0f)\n}\n\ninternal const val MaxProgressArc = 0.8f\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/pullrefresh/SwipeRefresh.kt",
    "content": "/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n\npackage com.shicheeng.copymanga.ui.screen.compoents.pullrefresh\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.MutatorMutex\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.nestedscroll.NestedScrollConnection\nimport androidx.compose.ui.input.nestedscroll.NestedScrollSource\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.Velocity\nimport androidx.compose.ui.unit.dp\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.launch\nimport kotlin.math.absoluteValue\nimport kotlin.math.roundToInt\n\nprivate const val DragMultiplier = 0.5f\n\n/**\n * Creates a [SwipeRefreshState] that is remembered across compositions.\n *\n * Changes to [isRefreshing] will result in the [SwipeRefreshState] being updated.\n *\n * @param isRefreshing the value for [SwipeRefreshState.isRefreshing]\n */\n\n@Composable\nfun rememberSwipeRefreshState(\n    isRefreshing: Boolean,\n): SwipeRefreshState {\n    return remember {\n        SwipeRefreshState(\n            isRefreshing = isRefreshing\n        )\n    }.apply {\n        this.isRefreshing = isRefreshing\n    }\n}\n\n/**\n * A state object that can be hoisted to control and observe changes for [SwipeRefresh].\n *\n * In most cases, this will be created via [rememberSwipeRefreshState].\n *\n * @param isRefreshing the initial value for [SwipeRefreshState.isRefreshing]\n */\n\n@Stable\nclass SwipeRefreshState(\n    isRefreshing: Boolean,\n) {\n    private val _indicatorOffset = Animatable(0f)\n    private val mutatorMutex = MutatorMutex()\n\n    /**\n     * Whether this [SwipeRefreshState] is currently refreshing or not.\n     */\n    var isRefreshing: Boolean by mutableStateOf(isRefreshing)\n\n    /**\n     * Whether a swipe/drag is currently in progress.\n     */\n    var isSwipeInProgress: Boolean by mutableStateOf(false)\n        internal set\n\n    /**\n     * The current offset for the indicator, in pixels.\n     */\n    val indicatorOffset: Float get() = _indicatorOffset.value\n\n    internal suspend fun animateOffsetTo(offset: Float) {\n        mutatorMutex.mutate {\n            _indicatorOffset.animateTo(offset)\n        }\n    }\n\n    /**\n     * Dispatch scroll delta in pixels from touch events.\n     */\n    internal suspend fun dispatchScrollDelta(delta: Float) {\n        mutatorMutex.mutate(MutatePriority.UserInput) {\n            _indicatorOffset.snapTo(_indicatorOffset.value + delta)\n        }\n    }\n}\n\nprivate class SwipeRefreshNestedScrollConnection(\n    private val state: SwipeRefreshState,\n    private val coroutineScope: CoroutineScope,\n    private val onRefresh: () -> Unit,\n) : NestedScrollConnection {\n    var enabled: Boolean = false\n    var refreshTrigger: Float = 0f\n\n    override fun onPreScroll(\n        available: Offset,\n        source: NestedScrollSource,\n    ): Offset = when {\n        // If swiping isn't enabled, return zero\n        !enabled -> Offset.Zero\n        // If we're refreshing, return zero\n        state.isRefreshing -> Offset.Zero\n        // If the user is swiping up, handle it\n        source == NestedScrollSource.Drag && available.y < 0 -> onScroll(available)\n        else -> Offset.Zero\n    }\n\n    override fun onPostScroll(\n        consumed: Offset,\n        available: Offset,\n        source: NestedScrollSource,\n    ): Offset = when {\n        // If swiping isn't enabled, return zero\n        !enabled -> Offset.Zero\n        // If we're refreshing, return zero\n        state.isRefreshing -> Offset.Zero\n        // If the user is swiping down and there's y remaining, handle it\n        source == NestedScrollSource.Drag && available.y > 0 -> onScroll(available)\n        else -> Offset.Zero\n    }\n\n    private fun onScroll(available: Offset): Offset {\n        if (available.y > 0) {\n            state.isSwipeInProgress = true\n        } else if (state.indicatorOffset.roundToInt() == 0) {\n            state.isSwipeInProgress = false\n        }\n\n        val newOffset = (available.y * DragMultiplier + state.indicatorOffset).coerceAtLeast(0f)\n        val dragConsumed = newOffset - state.indicatorOffset\n\n        return if (dragConsumed.absoluteValue >= 0.5f) {\n            coroutineScope.launch {\n                state.dispatchScrollDelta(dragConsumed)\n            }\n            // Return the consumed Y\n            Offset(x = 0f, y = dragConsumed / DragMultiplier)\n        } else {\n            Offset.Zero\n        }\n    }\n\n    override suspend fun onPreFling(available: Velocity): Velocity {\n        // If we're dragging, not currently refreshing and scrolled\n        // past the trigger point, refresh!\n        if (!state.isRefreshing && state.indicatorOffset >= refreshTrigger) {\n            onRefresh()\n        }\n\n        // Reset the drag in progress state\n        state.isSwipeInProgress = false\n\n        // Don't consume any velocity, to allow the scrolling layout to fling\n        return Velocity.Zero\n    }\n}\n\n/**\n * A layout which implements the swipe-to-refresh pattern, allowing the user to refresh content via\n * a vertical swipe gesture.\n *\n * This layout requires its content to be scrollable so that it receives vertical swipe events.\n * The scrollable content does not need to be a direct descendant though. Layouts such as\n * [androidx.compose.foundation.lazy.LazyColumn] are automatically scrollable, but others such as\n * [androidx.compose.foundation.layout.Column] require you to provide the\n * [androidx.compose.foundation.verticalScroll] modifier to that content.\n *\n * Apps should provide a [onRefresh] block to be notified each time a swipe to refresh gesture\n * is completed. That block is responsible for updating the [state] as appropriately,\n * typically by setting [SwipeRefreshState.isRefreshing] to `true` once a 'refresh' has been\n * started. Once a refresh has completed, the app should then set\n * [SwipeRefreshState.isRefreshing] to `false`.\n *\n * If an app wishes to show the progress animation outside of a swipe gesture, it can\n * set [SwipeRefreshState.isRefreshing] as required.\n *\n * This layout does not clip any of it's contents, including the indicator. If clipping\n * is required, apps can provide the [androidx.compose.ui.draw.clipToBounds] modifier.\n *\n * @sample com.google.accompanist.sample.swiperefresh.SwipeRefreshSample\n *\n * @param state the state object to be used to control or observe the [SwipeRefresh] state.\n * @param onRefresh Lambda which is invoked when a swipe to refresh gesture is completed.\n * @param modifier the modifier to apply to this layout.\n * @param swipeEnabled Whether the the layout should react to swipe gestures or not.\n * @param refreshTriggerDistance The minimum swipe distance which would trigger a refresh.\n * @param indicatorAlignment The alignment of the indicator. Defaults to [Alignment.TopCenter].\n * @param indicatorPadding Content padding for the indicator, to inset the indicator in if required.\n * @param indicator the indicator that represents the current state. By default this\n * will use a [SwipeRefreshIndicator].\n * @param clipIndicatorToPadding Whether to clip the indicator to [indicatorPadding]. If false is\n * provided the indicator will be clipped to the [content] bounds. Defaults to true.\n * @param content The content containing a scroll composable.\n */\n\n@Composable\nfun SwipeRefresh(\n    state: SwipeRefreshState,\n    onRefresh: () -> Unit,\n    modifier: Modifier = Modifier,\n    swipeEnabled: Boolean = true,\n    refreshTriggerDistance: Dp = 80.dp,\n    indicatorAlignment: Alignment = Alignment.TopCenter,\n    indicatorPadding: PaddingValues = PaddingValues(0.dp),\n    indicator: @Composable (state: SwipeRefreshState, refreshTrigger: Dp) -> Unit = { s, trigger ->\n        SwipeRefreshIndicator(s, trigger)\n    },\n    clipIndicatorToPadding: Boolean = true,\n    content: @Composable () -> Unit,\n) {\n    val coroutineScope = rememberCoroutineScope()\n    val updatedOnRefresh = rememberUpdatedState(onRefresh)\n\n    // Our LaunchedEffect, which animates the indicator to its resting position\n    LaunchedEffect(state.isSwipeInProgress) {\n        if (!state.isSwipeInProgress) {\n            // If there's not a swipe in progress, rest the indicator at 0f\n            state.animateOffsetTo(0f)\n        }\n    }\n\n    val refreshTriggerPx = with(LocalDensity.current) { refreshTriggerDistance.toPx() }\n\n    // Our nested scroll connection, which updates our state.\n    val nestedScrollConnection = remember(state, coroutineScope) {\n        SwipeRefreshNestedScrollConnection(state, coroutineScope) {\n            // On refresh, re-dispatch to the update onRefresh block\n            updatedOnRefresh.value.invoke()\n        }\n    }.apply {\n        this.enabled = swipeEnabled\n        this.refreshTrigger = refreshTriggerPx\n    }\n\n    Box(modifier.nestedScroll(connection = nestedScrollConnection)) {\n        content()\n\n        Box(\n            Modifier\n                // If we're not clipping to the padding, we use clipToBounds() before the padding()\n                // modifier.\n                .let { if (!clipIndicatorToPadding) it.clipToBounds() else it }\n                .padding(indicatorPadding)\n                .matchParentSize()\n                // Else, if we're are clipping to the padding, we use clipToBounds() after\n                // the padding() modifier.\n                .let { if (clipIndicatorToPadding) it.clipToBounds() else it }\n        ) {\n            Box(Modifier.align(indicatorAlignment)) {\n                indicator(state, refreshTriggerDistance)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/compoents/pullrefresh/SwipeRefreshIndicator.kt",
    "content": "/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n\n\npackage com.shicheeng.copymanga.ui.screen.compoents.pullrefresh\n\nimport androidx.compose.animation.Crossfade\nimport androidx.compose.animation.core.LinearOutSlowInEasing\nimport androidx.compose.animation.core.animate\nimport androidx.compose.animation.core.tween\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.material3.CircularProgressIndicator\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\n\n/**\n * A class to encapsulate details of different indicator sizes.\n *\n * @param size The overall size of the indicator.\n * @param arcRadius The radius of the arc.\n * @param strokeWidth The width of the arc stroke.\n * @param arrowWidth The width of the arrow.\n * @param arrowHeight The height of the arrow.\n */\n@Immutable\nprivate data class SwipeRefreshIndicatorSizes(\n    val size: Dp,\n    val arcRadius: Dp,\n    val strokeWidth: Dp,\n    val arrowWidth: Dp,\n    val arrowHeight: Dp,\n)\n\n/**\n * The default/normal size values for [SwipeRefreshIndicator].\n */\nprivate val DefaultSizes = SwipeRefreshIndicatorSizes(\n    size = 40.dp,\n    arcRadius = 7.5.dp,\n    strokeWidth = 2.5.dp,\n    arrowWidth = 10.dp,\n    arrowHeight = 5.dp,\n)\n\n/**\n * The 'large' size values for [SwipeRefreshIndicator].\n */\nprivate val LargeSizes = SwipeRefreshIndicatorSizes(\n    size = 56.dp,\n    arcRadius = 11.dp,\n    strokeWidth = 3.dp,\n    arrowWidth = 12.dp,\n    arrowHeight = 6.dp,\n)\n\n/**\n * Indicator composable which is typically used in conjunction with [SwipeRefresh].\n *\n * @param state The [SwipeRefreshState] passed into the [SwipeRefresh] `indicator` block.\n * @param modifier The modifier to apply to this layout.\n * @param fade Whether the arrow should fade in/out as it is scrolled in. Defaults to true.\n * @param scale Whether the indicator should scale up/down as it is scrolled in. Defaults to false.\n * @param arrowEnabled Whether an arrow should be drawn on the indicator. Defaults to true.\n * @param backgroundColor The color of the indicator background surface.\n * @param contentColor The color for the indicator's contents.\n * @param shape The shape of the indicator background surface. Defaults to [CircleShape].\n * @param largeIndication Whether the indicator should be 'large' or not. Defaults to false.\n * @param elevation The size of the shadow below the indicator.\n */\n\n@Composable\nfun SwipeRefreshIndicator(\n    state: SwipeRefreshState,\n    refreshTriggerDistance: Dp,\n    modifier: Modifier = Modifier,\n    fade: Boolean = true,\n    scale: Boolean = false,\n    arrowEnabled: Boolean = true,\n    backgroundColor: Color = MaterialTheme.colorScheme.primary,\n    contentColor: Color = contentColorFor(backgroundColor),\n    shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),\n    refreshingOffset: Dp = 16.dp,\n    largeIndication: Boolean = false,\n    elevation: Dp = 6.dp,\n) {\n    val sizes = if (largeIndication) LargeSizes else DefaultSizes\n\n    val indicatorRefreshTrigger = with(LocalDensity.current) { refreshTriggerDistance.toPx() }\n\n    val indicatorHeight = with(LocalDensity.current) { sizes.size.roundToPx() }\n    val refreshingOffsetPx = with(LocalDensity.current) { refreshingOffset.toPx() }\n\n    val slingshot = rememberUpdatedSlingshot(\n        offsetY = state.indicatorOffset,\n        maxOffsetY = indicatorRefreshTrigger,\n        height = indicatorHeight,\n    )\n\n    var offset by remember { mutableFloatStateOf(0f) }\n\n    if (state.isSwipeInProgress) {\n        // If the user is currently swiping, we use the 'slingshot' offset directly\n        offset = slingshot.offset.toFloat()\n    } else {\n        // If there's no swipe currently in progress, animate to the correct resting position\n        LaunchedEffect(state.isRefreshing) {\n            animate(\n                initialValue = offset,\n                targetValue = when {\n                    state.isRefreshing -> indicatorHeight + refreshingOffsetPx\n                    else -> 0f\n                }\n            ) { value, _ ->\n                offset = value\n            }\n        }\n    }\n\n    val adjustedElevation = when {\n        state.isRefreshing -> elevation\n        offset > 0.5f -> elevation\n        else -> 0.dp\n    }\n\n    Surface(\n        modifier = modifier\n            .size(size = sizes.size)\n            .graphicsLayer {\n                // Translate the indicator according to the slingshot\n                translationY = offset - indicatorHeight\n\n                val scaleFraction = if (scale && !state.isRefreshing) {\n                    val progress = offset / indicatorRefreshTrigger.coerceAtLeast(1f)\n\n                    // We use LinearOutSlowInEasing to speed up the scale in\n                    LinearOutSlowInEasing\n                        .transform(progress)\n                        .coerceIn(0f, 1f)\n                } else 1f\n\n                scaleX = scaleFraction\n                scaleY = scaleFraction\n            },\n        shape = shape,\n        color = backgroundColor,\n        tonalElevation = adjustedElevation,\n        shadowElevation = adjustedElevation\n    ) {\n        val painter = remember { CircularProgressPainter() }\n        painter.arcRadius = sizes.arcRadius\n        painter.strokeWidth = sizes.strokeWidth\n        painter.arrowWidth = sizes.arrowWidth\n        painter.arrowHeight = sizes.arrowHeight\n        painter.arrowEnabled = arrowEnabled && !state.isRefreshing\n        painter.color = contentColor\n        val alpha = if (fade) {\n            (state.indicatorOffset / indicatorRefreshTrigger).coerceIn(0f, 1f)\n        } else {\n            1f\n        }\n        painter.alpha = alpha\n\n        painter.startTrim = slingshot.startTrim\n        painter.endTrim = slingshot.endTrim\n        painter.rotation = slingshot.rotation\n        painter.arrowScale = slingshot.arrowScale\n\n        // This shows either an Image with CircularProgressPainter or a CircularProgressIndicator,\n        // depending on refresh state\n        Crossfade(\n            targetState = state.isRefreshing,\n            animationSpec = tween(durationMillis = CrossfadeDurationMs),\n            label = \"Cross Fade Refresh\"\n        ) { refreshing ->\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                if (refreshing) {\n                    val circleSize = (sizes.arcRadius + sizes.strokeWidth) * 2\n                    CircularProgressIndicator(\n                        color = contentColor,\n                        strokeWidth = sizes.strokeWidth,\n                        modifier = Modifier.size(circleSize),\n                    )\n                } else {\n                    Image(\n                        painter = painter,\n                        contentDescription = \"Refreshing\"\n                    )\n                }\n            }\n        }\n    }\n}\n\nprivate const val CrossfadeDurationMs = 100\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/download/DownloadScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.download\n\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.LargeTopAppBar\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.work.WorkInfo\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun DownloadScreen(\n    viewModel: DownloadScreenViewModel = hiltViewModel(),\n    onCardClick: (String) -> Unit,\n    onNavigationClick: () -> Unit,\n) {\n\n    val topAppBarScrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()\n    val items by viewModel.items.collectAsState()\n\n    Scaffold(\n        topBar = {\n            LargeTopAppBar(\n                title = { Text(text = stringResource(id = R.string.download_manga)) },\n                scrollBehavior = topAppBarScrollBehavior,\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onNavigationClick\n                    )\n                }\n            )\n        },\n        modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n    ) { paddingValues ->\n        if (items != null) {\n            LazyColumn(contentPadding = paddingValues) {\n                items?.forEach { (t, u) ->\n                    item {\n                        Text(\n                            text = stringResource(\n                                id = when (t) {\n                                    WorkInfo.State.ENQUEUED -> R.string.waiting\n                                    WorkInfo.State.RUNNING -> R.string.downloading\n                                    WorkInfo.State.SUCCEEDED -> R.string.completed\n                                    WorkInfo.State.FAILED -> R.string.failure_download\n                                    WorkInfo.State.BLOCKED -> R.string.prerequisites_miss\n                                    WorkInfo.State.CANCELLED -> R.string.cancel\n                                }\n                            ),\n                            modifier = Modifier.padding(16.dp)\n                        )\n                    }\n                    items(u) {\n                        DownloadItem(\n                            downloadUiDataModel = it,\n                            onCancel = {\n                                viewModel.cancel(it.id)\n                            },\n                            onCardClick = {\n                                onCardClick(it.pathWord)\n                            }\n                        ) {\n                            if (it.isPause) {\n                                viewModel.resume(it.id)\n                            } else {\n                                viewModel.pause(it.id)\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/download/DownloadScreenComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.download\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.LinearProgressIndicator\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedCard\nimport androidx.compose.material3.ProgressIndicatorDefaults\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.work.WorkInfo\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.downloadmodel.DownloadUiDataModel\n\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun DownloadItem(\n    downloadUiDataModel: DownloadUiDataModel,\n    onCancel: () -> Unit,\n    onCardClick: () -> Unit,\n    onClick: () -> Unit,\n) {\n    val animatedProgressState = ProgressIndicatorDefaults.ProgressAnimationSpec\n    val progressAnimated by remember { mutableFloatStateOf(0f) }\n    val progressAnimatedAsState by animateFloatAsState(\n        targetValue = progressAnimated,\n        animationSpec = animatedProgressState,\n        label = \"progress_animated\"\n    )\n\n    OutlinedCard(\n        onClick = { onCardClick() },\n        modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)\n    ) {\n        Row(\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(8.dp)\n        ) {\n            AsyncImage(\n                model = downloadUiDataModel.localSavableMangaModel.mangaHistoryDataModel.url,\n                contentDescription = null,\n                modifier = Modifier\n                    .height(120.dp)\n                    .clip(MaterialTheme.shapes.medium)\n                    .aspectRatio(2f / 3f),\n                contentScale = ContentScale.Crop\n            )\n            Column(\n                modifier = Modifier\n                    .weight(1f)\n                    .padding(start = 16.dp, end = 12.dp)\n            ) {\n                Text(\n                    text = downloadUiDataModel.localSavableMangaModel.mangaHistoryDataModel.name,\n                    style = MaterialTheme.typography.titleMedium,\n                    color = MaterialTheme.colorScheme.onSurface\n                )\n                Text(\n                    text = \"%.2f%%\".format(downloadUiDataModel.percent * 100),\n                    style = MaterialTheme.typography.bodySmall,\n                    color = MaterialTheme.colorScheme.onSurfaceVariant\n                )\n                if (downloadUiDataModel.workerState == WorkInfo.State.RUNNING) {\n                    Text(\n                        text = downloadUiDataModel.getEtaString()?.toString()\n                            ?: stringResource(R.string.downloading),\n                        style = MaterialTheme.typography.bodySmall,\n                        color = MaterialTheme.colorScheme.onSurfaceVariant\n                    )\n                    StateProgressIndication(\n                        isIndeterminate = downloadUiDataModel.isIndeterminate,\n                        progress = progressAnimatedAsState,\n                        modifier = Modifier.padding(top = 8.dp)\n                    )\n                }\n            }\n            when (downloadUiDataModel.workerState) {\n                WorkInfo.State.RUNNING -> {\n                    StateButton(\n                        isPause = downloadUiDataModel.isPause,\n                        modifier = Modifier\n                            .padding(end = 16.dp)\n                            .align(Alignment.CenterVertically),\n                        onClick = onClick\n                    )\n                }\n\n                WorkInfo.State.ENQUEUED -> {\n                    StateButton(\n                        id = R.drawable.baseline_close_24,\n                        contentDescription = stringResource(R.string.cancel),\n                        onClick = onCancel,\n                        modifier = Modifier\n                            .padding(end = 16.dp)\n                            .align(Alignment.CenterVertically)\n                    )\n                }\n\n                else -> {}\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun StateProgressIndication(\n    modifier: Modifier = Modifier,\n    isIndeterminate: Boolean,\n    progress: Float,\n) {\n    Box(\n        modifier = modifier,\n        contentAlignment = Alignment.CenterStart\n    ) {\n        if (!isIndeterminate) {\n            LinearProgressIndicator(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .clip(CircleShape),\n                progress = progress\n            )\n        } else {\n            LinearProgressIndicator(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .clip(CircleShape),\n            )\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/download/DownloadScreenViewModel.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.download\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.work.Data\nimport androidx.work.WorkInfo\nimport com.shicheeng.copymanga.data.downloadmodel.DownloadUiDataModel\nimport com.shicheeng.copymanga.data.local.LocalSavableMangaModel\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport com.shicheeng.copymanga.server.download.domin.DownloadState\nimport com.shicheeng.copymanga.server.download.woker.DownloadedWorker\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.mapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.plus\nimport kotlinx.coroutines.sync.Mutex\nimport kotlinx.coroutines.sync.withLock\nimport java.util.UUID\nimport javax.inject.Inject\n\n@HiltViewModel\nclass DownloadScreenViewModel @Inject constructor(\n    private val downloaderWorker: DownloadedWorker.Caller,\n    private val mangaHistoryRepository: MangaHistoryRepository,\n) : ViewModel() {\n\n    private val mangaCache = LinkedHashMap<String, LocalSavableMangaModel>()\n    private val mutexCache = Mutex()\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    private val workerData = downloaderWorker.observerWorker()\n        .mapLatest {\n            it.mapToUiDataModel()\n        }.stateIn(\n            scope = viewModelScope + Dispatchers.Default,\n            initialValue = null,\n            started = SharingStarted.Eagerly\n        )\n\n    val items = workerData.map { dataModels ->\n        dataModels?.groupBy { it.workerState }\n    }.stateIn(\n        scope = viewModelScope,\n        initialValue = emptyMap(),\n        started = SharingStarted.Eagerly\n    )\n\n    fun resume(id: UUID) {\n        val snapshot = workerData.value ?: return\n        for (work in snapshot) {\n            if (id == work.id) {\n                downloaderWorker.resume(id)\n            }\n        }\n    }\n\n    fun cancel(id: UUID) = viewModelScope.launch {\n        val snapshot = workerData.value ?: return@launch\n        for (work in snapshot) {\n            if (id == work.id) {\n                downloaderWorker.cancel(id)\n            }\n        }\n    }\n\n    fun pause(id: UUID) {\n        val snapshot = workerData.value ?: return\n        for (work in snapshot) {\n            if (id == work.id) {\n                downloaderWorker.pause(id)\n            }\n        }\n    }\n\n    private suspend fun List<WorkInfo>.mapToUiDataModel(): List<DownloadUiDataModel> {\n        if (isEmpty()) {\n            return emptyList()\n        }\n        val list = mapNotNullTo(ArrayList(size)) { it.toWorkUiDataModel() }\n        list.sortedByDescending { it.timeStamp }\n        return list\n    }\n\n    private suspend fun WorkInfo.toWorkUiDataModel(): DownloadUiDataModel? {\n        val data = if (outputData == Data.EMPTY) progress else outputData\n        val pathWord = (DownloadState getMangaPathWord data) ?: return null\n        val manga = getManga(pathWord) ?: return null\n        return DownloadUiDataModel(\n            pathWord = pathWord,\n            workerState = state,\n            localSavableMangaModel = manga,\n            isStopped = DownloadState isStoppedIn data,\n            isPause = DownloadState isPauseIn data,\n            isIndeterminate = DownloadState indeterminateFor data,\n            max = DownloadState getMax data,\n            totalChapter = DownloadState.downloadChaptersIn(data).size,\n            error = DownloadState getError data,\n            progress = DownloadState getProgress data,\n            timeStamp = DownloadState timeStampWhich data,\n            id = id,\n            eta = DownloadState timeETAIn data\n        )\n    }\n\n\n    private suspend fun getManga(pathWord: String): LocalSavableMangaModel? {\n        mangaCache[pathWord]?.let {\n            return it\n        }\n        return mutexCache.withLock {\n            mangaCache.getOrElse(pathWord) {\n                mangaHistoryRepository.getMangaByPathWord(pathWord)\n                    ?.also {\n                        mangaCache[pathWord] = it\n                    } ?: return null\n            }\n        }\n    }\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/download/EmptyScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.download\n\nimport androidx.annotation.StringRes\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontStyle\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\n\n@Composable\nfun EmptyScreen(\n    paddingValues: PaddingValues = PaddingValues(0.dp),\n    @StringRes id: Int = R.string.empty_download,\n) {\n    Box(\n        modifier = Modifier\n            .fillMaxSize()\n            .padding(paddingValues),\n        contentAlignment = Alignment.Center\n    ) {\n        Column(\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Image(\n                painter = painterResource(id = R.drawable.undraw_no_data_re_kwbl),\n                contentDescription = null,\n            )\n            Spacer(modifier = Modifier.height(8.dp))\n            Text(\n                text = stringResource(id = id),\n                fontStyle = FontStyle.Italic,\n                color = MaterialTheme.colorScheme.onSurface\n            )\n        }\n\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/download/StateButton.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.download\n\nimport androidx.annotation.DrawableRes\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.theme.ElevationTokens\n\n@Composable\nfun StateButton(\n    modifier: Modifier = Modifier,\n    size: Dp = 48.dp,\n    isPause: Boolean,\n    onClick: () -> Unit,\n) {\n\n    val interaction = remember { MutableInteractionSource() }\n    val isPressed by interaction.collectIsPressedAsState()\n    val cornerSize by animateDpAsState(\n        label = \"state_button_size\",\n        targetValue = if (isPressed || isPressed) {\n            size\n        } else {\n            12.dp\n        }\n    )\n\n    Surface(\n        onClick = onClick,\n        tonalElevation = ElevationTokens.Level3,\n        shape = RoundedCornerShape(cornerSize),\n        interactionSource = interaction,\n        modifier = modifier.size(size)\n    ) {\n        Box(\n            modifier = Modifier.fillMaxSize(),\n            contentAlignment = Alignment.Center\n        ) {\n            Icon(\n                painter = painterResource(\n                    id = if (isPause) {\n                        R.drawable.baseline_play_arrow_24\n                    } else {\n                        R.drawable.baseline_pause_24\n                    }\n                ),\n                contentDescription = stringResource(id = if (isPause) R.string.resume else R.string.pause)\n            )\n        }\n    }\n}\n\n/**\n * 圆角可变换的按钮\n * @param size 大小\n * @param id 图片资源id\n * @param contentDescription 辅助服务使用的文本来描述该图标所代表的含义。 应始终提供此图标，除非该图标用于装饰目的，并且不代表用户可以采取的有意义的操作。 该文本应该本地化，例如使用 [androidx.compose.ui.res.stringResource] 或类似。\n * @param onClick 点击事件回调\n */\n@Composable\nfun StateButton(\n    modifier: Modifier = Modifier,\n    size: Dp = 48.dp,\n    @DrawableRes id: Int,\n    contentDescription: String?,\n    onClick: () -> Unit,\n) {\n\n    val interaction = remember { MutableInteractionSource() }\n    val isPressed by interaction.collectIsPressedAsState()\n    val cornerSize by animateDpAsState(\n        label = \"state_button_size\",\n        targetValue = if (isPressed || isPressed) {\n            size\n        } else {\n            12.dp\n        }\n    )\n\n    Surface(\n        onClick = onClick,\n        tonalElevation = ElevationTokens.Level3,\n        shape = RoundedCornerShape(cornerSize),\n        interactionSource = interaction,\n        modifier = modifier.size(size)\n    ) {\n        Box(\n            modifier = Modifier.fillMaxSize(),\n            contentAlignment = Alignment.Center\n        ) {\n            Icon(\n                painter = painterResource(id = id),\n                contentDescription = contentDescription\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/downloaded/Downloaded.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.downloaded\n\nimport android.net.Uri\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.PersonalInnerDataModel\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.download.EmptyScreen\nimport com.shicheeng.copymanga.util.copyComposable\nimport com.shicheeng.copymanga.viewmodel.DownloadViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun DownloadedScreen(\n    cViewModel: DownloadViewModel = hiltViewModel(),\n    onNavigate: () -> Unit,\n    onClick: (String?) -> Unit,\n) {\n    val list by cViewModel.list.collectAsState()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = { Text(text = stringResource(R.string.download_manga)) },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onNavigate\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n        if (list.isEmpty()) {\n            EmptyScreen(paddingValues = paddingValues)\n        } else {\n            LazyVerticalGrid(\n                contentPadding = paddingValues.copyComposable(\n                    start = 16.dp, end = 16.dp\n                ),\n                columns = GridCells.Fixed(3),\n                verticalArrangement = Arrangement.spacedBy(16.dp),\n                horizontalArrangement = Arrangement.spacedBy(16.dp)\n            ) {\n                items(list) { innerItem: PersonalInnerDataModel? ->\n                    innerItem?.let {\n                        DownloadedListItem(url = innerItem.url, title = innerItem.name) {\n                            if (innerItem.pathWord != null) {\n                                onClick(innerItem.pathWord)\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun DownloadedListItem(\n    url: Uri?,\n    title: String,\n    onClick: () -> Unit,\n) {\n    Card(\n        modifier = Modifier.width(IntrinsicSize.Min),\n        onClick = onClick\n    ) {\n        Column(\n            modifier = Modifier.padding(bottom = 4.dp)\n        ) {\n            AsyncImage(\n                model = url,\n                contentDescription = null,\n                placeholder = ColorPainter(MaterialTheme.colorScheme.primary),\n                modifier = Modifier\n                    .clip(MaterialTheme.shapes.medium)\n                    .aspectRatio(2f / 3f),\n                contentScale = ContentScale.Crop\n            )\n            Text(\n                text = title,\n                style = MaterialTheme.typography.titleSmall,\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis,\n                modifier = Modifier.padding(4.dp)\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/downloaded/DownloadedResolveDialog.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.downloaded\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.window.Dialog\n\n@Composable\nfun DownloadedResolveDialog() = Dialog(onDismissRequest = { /*TODO*/ }) {\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/error/ErrorScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.error\n\nimport android.content.Context\nimport android.content.Intent\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.scrollable\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.material3.FilledTonalButton\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\n\n@Composable\nfun ErrorScreen(\n    message: String?,\n    onFinishClick: () -> Unit,\n) {\n\n    val scrollState = rememberScrollState()\n    val context = LocalContext.current\n\n    Surface(\n        modifier = Modifier.fillMaxSize()\n    ) {\n        Column(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(all = 16.dp),\n        ) {\n            Text(\n                text = stringResource(R.string.fatal_error),\n                style = MaterialTheme.typography.headlineMedium,\n                color = MaterialTheme.colorScheme.onSurface\n            )\n            Text(\n                text = stringResource(R.string.try_to_send_to_me),\n                style = MaterialTheme.typography.titleMedium,\n                color = MaterialTheme.colorScheme.onSurfaceVariant\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            Text(\n                text = message ?: stringResource(id = R.string.no_content),\n                modifier = Modifier\n                    .weight(1f)\n                    .scrollable(\n                        state = scrollState,\n                        orientation = Orientation.Vertical\n                    )\n            )\n            FilledTonalButton(\n                onClick = {\n                    context.composeEmail(\n                        addresses = arrayOf(\"sshizzhi1234@gmail.com\"),\n                        body = message ?: \"\"\n                    )\n                },\n                modifier = Modifier.align(Alignment.End)\n            ) {\n                Text(text = stringResource(R.string.send))\n            }\n            FilledTonalButton(\n                onClick = onFinishClick,\n                modifier = Modifier.align(Alignment.End)\n            ) {\n                Text(text = stringResource(R.string.finish_this))\n            }\n        }\n\n    }\n}\n\nfun Context.composeEmail(addresses: Array<String>, body: String) {\n    val intent = Intent(Intent.ACTION_SEND).apply {\n        type = \"*/*\"\n        putExtra(Intent.EXTRA_EMAIL, addresses)\n        putExtra(Intent.EXTRA_TEXT, body)\n    }\n    startActivity(intent)\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/history/History.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.history\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.PrimaryTabRow\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Tab\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveableStateHolder\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.SaveStatePager\nimport com.shicheeng.copymanga.ui.screen.compoents.withAppBarColor\nimport com.shicheeng.copymanga.ui.screen.history.local.LocalHistoryScreen\nimport com.shicheeng.copymanga.ui.screen.history.web.WebHistoryScreen\nimport com.shicheeng.copymanga.util.copyComposable\nimport kotlinx.coroutines.launch\n\n@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)\n@Composable\nfun HistoryScreen(\n    navigationClick: () -> Unit,\n    onRequestLogin: () -> Unit,\n    onPathWord: (String) -> Unit,\n) {\n\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val stringIds = rememberHistoryWord()\n    val pagerState = rememberPagerState(pageCount = stringIds::size)\n    val savableState = rememberSaveableStateHolder()\n    val coroutineScope = rememberCoroutineScope()\n\n    Scaffold(\n        topBar = {\n            Column(\n                modifier = Modifier.fillMaxWidth()\n            ) {\n                TopAppBar(\n                    title = { Text(text = stringResource(id = R.string.history)) },\n                    scrollBehavior = topAppBarScrollBehavior,\n                    navigationIcon = {\n                        PlainButton(\n                            id = R.string.back_to_up,\n                            drawableRes = R.drawable.ic_arrow_back,\n                            onButtonClick = navigationClick\n                        )\n                    }\n                )\n                PrimaryTabRow(\n                    selectedTabIndex = pagerState.currentPage,\n                    containerColor = withAppBarColor(topAppBarState = topAppBarScrollBehavior.state),\n                ) {\n                    for (i in 0 until pagerState.pageCount) {\n                        val interactionSource = remember(::MutableInteractionSource)\n                        Tab(\n                            selected = pagerState.currentPage == i,\n                            onClick = {\n                                coroutineScope.launch {\n                                    pagerState.animateScrollToPage(i)\n                                }\n                            },\n                            text = {\n                                Text(text = stringResource(id = stringIds[i]))\n                            },\n                            modifier = Modifier,\n                            interactionSource = interactionSource\n                        )\n                    }\n                }\n            }\n\n        }\n    ) { paddingValues ->\n        SaveStatePager(\n            pagerState = pagerState,\n            contentPadding = paddingValues.copyComposable(\n                bottom = 0.dp\n            ),\n            savableStateHolder = savableState,\n            keys = { stringIds },\n            modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n        ) { index ->\n            when (index) {\n                0 -> {\n                    LocalHistoryScreen(\n                        onPathWord = onPathWord,\n                        bottomPadding = paddingValues.calculateBottomPadding()\n                    )\n                }\n\n                1 -> {\n                    WebHistoryScreen(\n                        onPathWord = onPathWord,\n                        onRequestLogin = onRequestLogin,\n                        bottomPadding = paddingValues.calculateBottomPadding()\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun rememberHistoryWord() = remember {\n    listOf(\n        R.string.local_history,\n        R.string.web_history\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/history/local/HistoryComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.history.local\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.webhistory.WebHistoryItem\nimport com.shicheeng.copymanga.ui.screen.compoents.CommonCover\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.util.convertToOnlyTime\n\n@Composable\nfun HistoryItem(\n    modifier: Modifier = Modifier,\n    data: MangaHistoryDataModel,\n    onClick: () -> Unit,\n    onDeleteClick: () -> Unit,\n) {\n    Row(\n        modifier = modifier\n            .clickable(onClick = onClick)\n            .fillMaxWidth()\n            .padding(horizontal = 16.dp, vertical = 8.dp),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Card(\n            modifier = Modifier.width(50.dp),\n            shape = RoundedCornerShape(4.dp)\n        ) {\n            CommonCover(\n                url = data.url,\n                contentDescription = data.name,\n                shape = RoundedCornerShape(size = 4.dp)\n            )\n        }\n        Column(\n            modifier = Modifier\n                .padding(start = 8.dp)\n                .weight(1f)\n        ) {\n            Text(\n                text = data.name,\n                style = MaterialTheme.typography.titleMedium,\n                color = MaterialTheme.colorScheme.onSurface,\n            )\n            Text(\n                text = \"${data.time.convertToOnlyTime()} • ${\n                    stringResource(\n                        id = R.string.info_read_in,\n                        formatArgs = arrayOf(data.positionChapter + 1, data.positionPage + 1)\n                    )\n                }\",\n                style = MaterialTheme.typography.titleSmall,\n                modifier = Modifier.padding(top = 2.dp),\n                color = MaterialTheme.colorScheme.onSurfaceVariant\n            )\n        }\n        PlainButton(\n            id = R.string.delete,\n            drawableRes = R.drawable.baseline_delete_outline_24,\n            onButtonClick = onDeleteClick\n        )\n    }\n}\n\n@Composable\nfun HistoryItemCloud(\n    modifier: Modifier = Modifier,\n    data: WebHistoryItem,\n    onClick: () -> Unit,\n) {\n    Row(\n        modifier = modifier\n            .clickable(onClick = onClick)\n            .fillMaxWidth()\n            .padding(horizontal = 16.dp, vertical = 8.dp),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Card(\n            modifier = Modifier.width(50.dp),\n            shape = RoundedCornerShape(4.dp)\n        ) {\n            CommonCover(\n                url = data.comic.cover,\n                contentDescription = data.comic.name,\n                shape = RoundedCornerShape(size = 4.dp)\n            )\n        }\n        Column(\n            modifier = Modifier\n                .padding(start = 8.dp)\n                .weight(1f)\n        ) {\n            Text(\n                text = data.comic.name,\n                style = MaterialTheme.typography.titleMedium,\n                color = MaterialTheme.colorScheme.onSurface,\n            )\n            Text(\n                text = data.lastChapterName,\n                style = MaterialTheme.typography.titleSmall,\n                modifier = Modifier.padding(top = 2.dp, end = 8.dp),\n                color = MaterialTheme.colorScheme.onSurfaceVariant\n            )\n        }\n        PlainButton(\n            id = R.string.shelf_cloud,\n            drawableRes = R.drawable.outline_cloud_24\n        ) {}\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/history/local/LocalHistoryScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.history.local\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.download.EmptyScreen\nimport com.shicheeng.copymanga.util.convertToTimeGroup\nimport com.shicheeng.copymanga.viewmodel.HistoryViewModel\n\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\nfun LocalHistoryScreen(\n    historyViewModel: HistoryViewModel = hiltViewModel(),\n    bottomPadding: Dp,\n    onPathWord: (String) -> Unit,\n) {\n\n    val historyList by historyViewModel.historyList.collectAsState()\n    val historyGrouped = historyList\n        .filter { it.positionChapter != 0 || it.positionPage != 0 }\n        .groupBy { it.time.convertToTimeGroup() }\n\n    Box(\n        modifier = Modifier.fillMaxSize()\n    ) {\n        if (historyList.isEmpty()) {\n            EmptyScreen(id = R.string.no_history)\n        } else {\n            LazyColumn(\n                modifier = Modifier.fillMaxSize(),\n                contentPadding = PaddingValues(bottom = bottomPadding, top = 16.dp)\n            ) {\n                historyGrouped.forEach { stringListEntry ->\n                    if (stringListEntry.value.isNotEmpty()) {\n                        item(\n                            key = stringListEntry.hashCode(),\n                            contentType = \"HEADER\"\n                        ) {\n                            Text(\n                                text = stringListEntry.key,\n                                modifier = Modifier\n                                    .padding(horizontal = 16.dp, vertical = 4.dp)\n                                    .animateItemPlacement()\n                            )\n                        }\n                    }\n                    items(\n                        stringListEntry.value,\n                        key = { \"history-${it.hashCode()}\" },\n                        contentType = {\n                            \"item\"\n                        }\n                    ) { historyItem ->\n                        HistoryItem(\n                            data = historyItem,\n                            onClick = {\n                                onPathWord(historyItem.pathWord)\n                            },\n                            modifier = Modifier.animateItemPlacement()\n                        ) {\n                            historyViewModel.deleteHistory(historyItem)\n                        }\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/history/web/WebHistoryScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.history.web\n\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.material.pullrefresh.rememberPullRefreshState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.LoadState\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.RefreshLayout\nimport com.shicheeng.copymanga.ui.screen.history.local.HistoryItemCloud\nimport retrofit2.HttpException\n\n@OptIn(ExperimentalMaterialApi::class)\n@Composable\nfun WebHistoryScreen(\n    viewModel: WebHistoryViewModel = hiltViewModel(),\n    bottomPadding: Dp,\n    onPathWord: (String) -> Unit,\n    onRequestLogin: () -> Unit,\n) {\n    val list = viewModel.list.collectAsLazyPagingItems()\n    val refreshState = rememberPullRefreshState(\n        refreshing = list.loadState.refresh is LoadState.Loading,\n        onRefresh = {\n            list.refresh()\n        }\n    )\n\n    if (list.loadState.refresh is LoadState.Loading) {\n        LoadingScreen()\n        return\n    }\n\n    if (list.loadState.refresh is LoadState.Error) {\n        val error = (list.loadState.refresh as LoadState.Error).error\n        ErrorScreen(\n            errorMessage = error.message ?: \"\",\n            onTry = { list.refresh() },\n            needSecondaryText = error is HttpException && error.code() == 401,\n            secondaryText = stringResource(id = R.string.re_login),\n            onSecondaryClick = onRequestLogin\n        )\n        return\n    }\n\n    RefreshLayout(\n        pullRefreshState = refreshState,\n        isRefreshing = list.loadState.refresh is LoadState.Loading,\n        topPadding = 0.dp\n    ) {\n        LazyColumn(\n            contentPadding = PaddingValues(bottom = bottomPadding, top = 16.dp)\n        ) {\n            items(list.itemCount) { index ->\n                list[index]?.let { item ->\n                    HistoryItemCloud(data = item) {\n                        onPathWord(item.comic.pathWord)\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/history/web/WebHistoryViewModel.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.history.web\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.resposity.WebHistoryRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport javax.inject.Inject\n\n@HiltViewModel\nclass WebHistoryViewModel @Inject constructor(\n    webHistoryRepository: WebHistoryRepository,\n) : ViewModel() {\n\n    val list = webHistoryRepository.historyOnWeb().cachedIn(viewModelScope)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/list/CommonListComponent.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.list\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.ui.screen.compoents.CommonCover\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun CommonListItem(\n    url: String,\n    title: String,\n    author: String,\n    onClick: () -> Unit,\n) {\n    Card(\n        modifier = Modifier.width(IntrinsicSize.Min),\n        onClick = onClick\n    ) {\n        Column(\n            modifier = Modifier.padding(bottom = 4.dp)\n        ) {\n            CommonCover(url = url, contentDescription = title)\n            Text(\n                text = title,\n                style = MaterialTheme.typography.titleSmall,\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis\n            )\n            Text(\n                text = author,\n                style = MaterialTheme.typography.bodySmall,\n                modifier = Modifier.alpha(0.78f),\n                overflow = TextOverflow.Ellipsis,\n                maxLines = 1\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/list/NewestScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.list\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.viewmodel.MangaNewestListViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun NewestScreen(\n    recommendViewModel: MangaNewestListViewModel = hiltViewModel(),\n    onBack: () -> Unit,\n    onPathWord: (String) -> Unit,\n) {\n    val list = recommendViewModel.list.collectAsLazyPagingItems()\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val layoutDirection = LocalLayoutDirection.current\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = { Text(text = stringResource(id = R.string.new_manga)) },\n                scrollBehavior = topAppBarScrollBehavior,\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onBack\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n        LazyVerticalGrid(\n            columns = GridCells.Fixed(3),\n            contentPadding = paddingValues.copy(\n                layoutDirection = layoutDirection,\n                bottom = paddingValues.calculateBottomPadding(),\n                start = 16.dp,\n                end = 16.dp\n            ),\n            verticalArrangement = Arrangement.spacedBy(8.dp),\n            horizontalArrangement = Arrangement.spacedBy(8.dp)\n        ) {\n            items(list.itemCount) { itemIndex ->\n                list[itemIndex]?.let { item ->\n                    CommonListItem(\n                        url = item.comic.cover,\n                        title = item.comic.name,\n                        author = item.comic.authorReformation()\n                    ) {\n                        onPathWord.invoke(item.comic.pathWord)\n                    }\n                }\n            }\n            pagingLoadingIndication(\n                loadState = list.loadState.append\n            ) {\n                list.retry()\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/list/RecommendScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.list\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.viewmodel.MangaRecommendListViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun RecommendScreen(\n    recommendViewModel: MangaRecommendListViewModel = hiltViewModel(),\n    onBack: () -> Unit,\n    onPathWord: (String) -> Unit,\n) {\n    val list = recommendViewModel.recommendMangaList.collectAsLazyPagingItems()\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val layoutDirection = LocalLayoutDirection.current\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = { Text(text = stringResource(id = R.string.recommend)) },\n                scrollBehavior = topAppBarScrollBehavior,\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onBack\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n        LazyVerticalGrid(\n            columns = GridCells.Fixed(3),\n            contentPadding = paddingValues.copy(\n                layoutDirection = layoutDirection,\n                bottom = paddingValues.calculateBottomPadding(),\n                start = 16.dp,\n                end = 16.dp\n            ),\n            verticalArrangement = Arrangement.spacedBy(8.dp),\n            horizontalArrangement = Arrangement.spacedBy(8.dp)\n        ) {\n            items(list.itemCount) { itemIndex ->\n                list[itemIndex]?.let { item ->\n                    CommonListItem(\n                        url = item.comic.cover,\n                        title = item.comic.name,\n                        author = item.comic.authorReformation()\n                    ) {\n                        onPathWord.invoke(item.comic.pathWord)\n                    }\n                }\n            }\n            pagingLoadingIndication(\n                loadState = list.loadState.append,\n                onTry = list::retry\n            )\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/login/LoginScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.login\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.text.input.PasswordVisualTransformation\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.CircleLoadingButton\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.util.LoginState\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun LoginScreen(\n    viewModel: LoginViewModel = hiltViewModel(),\n    onNavClick: () -> Unit,\n    onLoadingSuccess: () -> Unit,\n) {\n\n    val (username, onUsername) = rememberSaveable { mutableStateOf(\"\") }\n    val (password, onPassword) = rememberSaveable { mutableStateOf(\"\") }\n    val loginState by viewModel.loginStatus.collectAsState()\n    var isPasswordError by remember { mutableStateOf(false) }\n    var isUsernameError by remember { mutableStateOf(false) }\n    var isPasswordVisible by remember { mutableStateOf(false) }\n\n    LaunchedEffect(key1 = loginState) {\n        if (loginState is LoginState.Success) {\n            onLoadingSuccess()\n        }\n    }\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(R.string.login_text))\n                },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onNavClick\n                    )\n                }\n            )\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(it),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Image(\n                painter = painterResource(id = R.drawable.undraw_login_re),\n                contentDescription = null,\n                modifier = Modifier\n                    .size(200.dp)\n                    .clip(MaterialTheme.shapes.large),\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            OutlinedTextField(\n                value = username,\n                onValueChange = onUsername,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 16.dp),\n                label = {\n                    Text(text = stringResource(R.string.user_name_text))\n                },\n                singleLine = true,\n                isError = isUsernameError\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            OutlinedTextField(\n                value = password,\n                onValueChange = onPassword,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(horizontal = 16.dp),\n                label = {\n                    Text(text = stringResource(R.string.password_text))\n                },\n                keyboardOptions = KeyboardOptions(\n                    keyboardType = KeyboardType.Password,\n                ),\n                singleLine = true,\n                isError = loginState is LoginState.Error<*> || isPasswordError,\n                visualTransformation = if (!isPasswordVisible) {\n                    PasswordVisualTransformation()\n                } else {\n                    VisualTransformation.None\n                },\n                trailingIcon = {\n                    PlainButton(\n                        id = { R.string.password_text },\n                        drawableRes = {\n                            if (isPasswordVisible) {\n                                R.drawable.baseline_visibility_off_24\n                            } else {\n                                R.drawable.baseline_visibility_24\n                            }\n                        }\n                    ) {\n                        isPasswordVisible = !isPasswordVisible\n                    }\n                }\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            CircleLoadingButton(\n                isLoading = loginState == LoginState.Loading,\n                onClick = {\n                    when {\n                        username.isEmptyOrBlank() -> isUsernameError = true\n                        password.isEmptyOrBlank() -> isPasswordError = true\n                        password.isEmptyOrBlank() && username.isEmptyOrBlank() -> {\n                            isPasswordError = true\n                            isUsernameError = true\n                        }\n\n                        else -> {\n                            viewModel.loginUP(username, password)\n                        }\n                    }\n                }\n            )\n        }\n    }\n}\n\n\nprivate fun String.isEmptyOrBlank() = this.isEmpty() || this.isBlank()"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/login/LoginViewModel.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.login\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.resposity.LoginRepository\nimport com.shicheeng.copymanga.util.LoginState\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.combine\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass LoginViewModel @Inject constructor(\n    private val repository: LoginRepository,\n) : ViewModel() {\n\n    private val _username = MutableStateFlow(\"\")\n    private val _password = MutableStateFlow(\"\")\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val loginStatus = combine(_username, _password) { u, p ->\n        UPPackage(u, p)\n    }.filter {\n        it.notEmptyOrBlank()\n    }.flatMapLatest {\n        repository.login(username = it.username, password = it.password)\n    }.stateIn(\n        scope = viewModelScope,\n        started = SharingStarted.Eagerly,\n        initialValue = LoginState.NoStatus\n    )\n\n    fun loginUP(username: String, password: String) = viewModelScope.launch {\n        _username.emit(username)\n        _password.emit(password)\n    }\n\n    data class UPPackage(\n        val username: String,\n        val password: String,\n    ) {\n        fun notEmptyOrBlank(): Boolean {\n            return username.isNotBlank()\n                    && password.isNotBlank()\n                    && username.isNotEmpty()\n                    && password.isNotEmpty()\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/login/loginlist/LoginPeronsalItem.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.login.loginlist\n\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.IconButton\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.RadioButton\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.login.LocalLoginDataModel\nimport com.shicheeng.copymanga.ui.screen.main.personal.hostFor\n\n@Composable\nfun LoginPersonalSelection(\n    modifier: Modifier = Modifier,\n    isSelected: Boolean,\n    localLoginDataModel: LocalLoginDataModel,\n    onDelete: () -> Unit,\n    onClick: () -> Unit,\n) {\n\n    val mutableInteraction = remember(::MutableInteractionSource)\n\n    Row(\n        modifier = modifier\n            .fillMaxWidth()\n            .selectable(\n                selected = isSelected,\n                onClick = onClick,\n                indication = LocalIndication.current,\n                interactionSource = mutableInteraction\n            )\n            .padding(horizontal = 16.dp, vertical = 8.dp),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        RadioButton(\n            selected = isSelected,\n            onClick = onClick,\n            interactionSource = mutableInteraction\n        )\n        AsyncImage(\n            model = hostFor(localLoginDataModel.avatarImageUrl),\n            contentDescription = null,\n            modifier = Modifier\n                .size(48.dp)\n                .clip(CircleShape),\n            placeholder = ColorPainter(color = MaterialTheme.colorScheme.primary)\n        )\n        Column(\n            modifier = Modifier\n                .weight(1f)\n                .padding(start = 16.dp)\n        ) {\n            Text(\n                text = localLoginDataModel.nikeName,\n                style = MaterialTheme.typography.titleMedium\n            )\n            Text(\n                text = localLoginDataModel.userName,\n                style = MaterialTheme.typography.titleSmall\n            )\n        }\n        IconButton(onClick = onDelete) {\n            Icon(\n                painter = painterResource(id = R.drawable.baseline_delete_24),\n                contentDescription = stringResource(id = R.string.delete)\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/login/loginlist/LoginPersonListScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.login.loginlist\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.FloatingActionButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.viewmodel.LoginPersonalListViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun LoginPersonalListScreen(\n    viewModel: LoginPersonalListViewModel = hiltViewModel(),\n    onAddClicked: () -> Unit,\n    navigationClick: () -> Unit,\n) {\n    val list by viewModel.personalList.collectAsState()\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(R.string.login_personal))\n                },\n                scrollBehavior = topAppBarScrollBehavior,\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = navigationClick\n                    )\n                }\n            )\n        },\n        floatingActionButton = {\n            FloatingActionButton(onClick = onAddClicked) {\n                Icon(\n                    painter = painterResource(id = R.drawable.baseline_add_24),\n                    contentDescription = stringResource(R.string.add)\n                )\n            }\n        }\n    ) { paddingValues ->\n        if (list.isEmpty()) {\n            Box(\n                modifier = Modifier.fillMaxSize(),\n                contentAlignment = Alignment.Center\n            ) {\n                Column(\n                    horizontalAlignment = Alignment.CenterHorizontally\n                ) {\n                    Image(\n                        painter = painterResource(id = R.drawable.undraw_no_data_re_kwbl),\n                        contentDescription = null,\n                    )\n                    Text(text = stringResource(id = R.string.no_login))\n                }\n            }\n        } else {\n            LazyColumn(\n                contentPadding = paddingValues,\n                modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n            ) {\n                items(list) {\n                    LoginPersonalSelection(\n                        isSelected = it.selected,\n                        localLoginDataModel = it,\n                        onDelete = {\n                            viewModel.delete(it)\n                        }\n                    ) {\n                        viewModel.selectUUId(it.userID)\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/MainScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.NavigationBar\nimport androidx.compose.material3.NavigationBarItem\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Snackbar\nimport androidx.compose.material3.SnackbarDuration\nimport androidx.compose.material3.SnackbarHost\nimport androidx.compose.material3.SnackbarHostState\nimport androidx.compose.material3.SnackbarResult\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.saveable.rememberSaveableStateHolder\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.Router\nimport com.shicheeng.copymanga.ui.screen.compoents.SaveStateContentPager\nimport com.shicheeng.copymanga.ui.screen.main.explore.ExploreScreen\nimport com.shicheeng.copymanga.ui.screen.main.home.HomeScreen\nimport com.shicheeng.copymanga.ui.screen.main.leaderboard.LeaderBoardScreen\nimport com.shicheeng.copymanga.ui.screen.main.personal.PersonalScreen\nimport com.shicheeng.copymanga.viewmodel.MainViewModel\nimport kotlinx.coroutines.launch\nimport retrofit2.HttpException\n\n@Composable\nfun MainScreen(\n    modifier: Modifier = Modifier,\n    mainViewModel: MainViewModel = hiltViewModel(),\n    onUUid: (String) -> Unit,\n    onDownloadedBtnClick: () -> Unit,\n    onSearchButtonClick: () -> Unit,\n    onSettingButtonClick: () -> Unit,\n    onRecommendHeaderLineClick: () -> Unit,\n    onNewestHeaderLineClick: () -> Unit,\n    onSubscribedClick: () -> Unit,\n    onHistoryClick: () -> Unit,\n    onLibraryClick: () -> Unit,\n    onPersonalHeaderClick: (isLogin: Boolean) -> Unit,\n    onTopicClick: (pathWord: String, type: Int) -> Unit,\n    onTopicHeaderLineClick: () -> Unit,\n    onFinishHeaderLineClick: () -> Unit,\n    onLoginExpireClick: () -> Unit,\n    onHotClick: () -> Unit,\n) {\n    val screens = listOf(\n        Router.HOME,\n        Router.LEADERBOARD,\n        Router.EXPLORE,\n        Router.PERSONAL\n    )\n    val corScope = rememberCoroutineScope()\n    val savableStateHolder = rememberSaveableStateHolder()\n    var selectIndex by rememberSaveable { mutableIntStateOf(0) }\n    val loginStatus by mainViewModel.loginInfoStatus.collectAsState()\n    val showSnack by mainViewModel.showSnackBar.collectAsState()\n    val snackStateHost = remember(::SnackbarHostState)\n    val localContext = LocalContext.current\n\n    LaunchedEffect(key1 = loginStatus) {\n        if (loginStatus != null && showSnack) {\n            if (loginStatus is HttpException && (loginStatus as HttpException).code() == 401) {\n                snackStateHost.showSnackbar(\n                    message = localContext.getString(R.string.login_expired),\n                    actionLabel = localContext.getString(R.string.re_login),\n                    duration = SnackbarDuration.Short\n                ).also {\n                    if (it == SnackbarResult.ActionPerformed) {\n                        onLoginExpireClick()\n                    }\n                    if (it == SnackbarResult.Dismissed) {\n                        mainViewModel.dismissShack()\n                    }\n                }\n                mainViewModel.dismissShack()\n            } else {\n                snackStateHost.showSnackbar(\n                    message = localContext.getString(R.string.login_failure),\n                    withDismissAction = true,\n                    duration = SnackbarDuration.Short\n                )\n                mainViewModel.dismissShack()\n            }\n        }\n    }\n\n    Scaffold(\n        bottomBar = {\n            NavigationBar {\n                screens.forEach { screen ->\n                    NavigationBarItem(\n                        selected = selectIndex == screens.indexOf(screen),\n                        onClick = {\n                            if (\n                                (selectIndex == screens.indexOf(screen)) &&\n                                (screen.name == Router.PERSONAL.name)\n                            ) {\n                                onSettingButtonClick()\n                            } else {\n                                selectIndex = screens.indexOf(screen)\n                            }\n                        },\n                        label = {\n                            Text(text = stringResource(id = screen.stringId!!))\n                        },\n                        icon = {\n                            Icon(\n                                painter = painterResource(\n                                    id = if (selectIndex == screens.indexOf(screen)) {\n                                        screen.onClickIcon!!\n                                    } else {\n                                        screen.drawableRes!!\n                                    }\n                                ),\n                                contentDescription = null\n                            )\n                        }\n                    )\n                }\n            }\n        },\n        modifier = modifier,\n        contentWindowInsets = WindowInsets(top = 0),\n        snackbarHost = {\n            SnackbarHost(hostState = snackStateHost) {\n                Snackbar(snackbarData = it)\n            }\n        },\n    ) { paddingValues ->\n        SaveStateContentPager(\n            contentPadding = paddingValues,\n            savableStateHolder = savableStateHolder,\n            currentPager = selectIndex\n        ) { index ->\n            when (index) {\n                0 -> {\n                    HomeScreen(\n                        onUUid = onUUid,\n                        onSearchButtonClick = onSearchButtonClick,\n                        onSettingButtonClick = onSettingButtonClick,\n                        onRecommendHeaderLineClick = onRecommendHeaderLineClick,\n                        onRankHeaderLineClick = {\n                            corScope.launch {\n                                selectIndex = 1\n                            }\n                        },\n                        onHotHeaderLineClick = onHotClick,\n                        onNewestHeaderLineClick = onNewestHeaderLineClick,\n                        onFinishHeaderLineClick = onFinishHeaderLineClick,\n                        onTopicsClickLineClick = onTopicHeaderLineClick,\n                        onTopicCardClick = {\n                            onTopicClick(it.pathWord, it.type)\n                        }\n                    )\n                }\n\n                1 -> {\n                    LeaderBoardScreen {\n                        onUUid(it.comic.pathWord)\n                    }\n                }\n\n                2 -> {\n                    ExploreScreen(\n                        top = null,\n                        theme = null,\n                        order = null,\n                    ) {\n                        onUUid(it.pathWord)\n                    }\n                }\n\n                3 -> {\n                    PersonalScreen(\n                        onHistoryClick = onHistoryClick,\n                        onLibraryClick = onLibraryClick,\n                        onDownloadClick = onDownloadedBtnClick,\n                        onSubscribedClick = onSubscribedClick,\n                        onPersonalHeaderClick = onPersonalHeaderClick\n                    ) {\n                        onSettingButtonClick()\n                    }\n                }\n            }\n        }\n    }\n\n    BackHandler(enabled = selectIndex != 0) {\n        selectIndex = 0\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/MainScreenViewModel.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main\n\nimport androidx.lifecycle.ViewModel\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport javax.inject.Inject\n\n@HiltViewModel\nclass MainScreenViewModel @Inject constructor() : ViewModel() {\n\n    private val _topWord = MutableStateFlow<String?>(null)\n    private val _orderWord = MutableStateFlow<String?>(null)\n    private val _themeWord = MutableStateFlow<String?>(null)\n\n    val order = _orderWord.asStateFlow()\n    val top = _topWord.asStateFlow()\n    val theme = _themeWord.asStateFlow()\n\n\n    fun addOrder(orderPathWord: String) {\n        _orderWord.tryEmit(orderPathWord)\n        _topWord.tryEmit(null)\n    }\n\n    fun addTop(topWord: String) {\n        _topWord.tryEmit(topWord)\n        _orderWord.tryEmit(null)\n    }\n\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/explore/ExploreComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.explore\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.data.finished.Item\nimport com.shicheeng.copymanga.ui.screen.compoents.CommonCover\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun ExploreItem(\n    modifier: Modifier = Modifier,\n    item: Item,\n    onItemClick: (Item) -> Unit,\n) {\n    Card(\n        modifier = modifier.width(IntrinsicSize.Min),\n        onClick = {\n            onItemClick.invoke(item)\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(bottom = 4.dp)\n                .wrapContentSize()\n        ) {\n            CommonCover(\n                url = item.cover,\n                contentDescription = item.name\n            )\n            Text(\n                text = item.name,\n                style = MaterialTheme.typography.titleSmall,\n                overflow = TextOverflow.Ellipsis,\n                maxLines = 1\n            )\n            Text(\n                text = item.authorReformation(),\n                style = MaterialTheme.typography.bodySmall,\n                modifier = Modifier.alpha(0.78f),\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/explore/ExploreFilterBottomSheet.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.explore\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.Divider\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.json.MangaSortJson\nimport com.shicheeng.copymanga.ui.screen.compoents.dimensionAttribute\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun ExploreFilterBottomSheet(\n    title: String,\n    list: List<MangaSortBean>,\n    sortBean: MangaSortBean?,\n    onSelected: (MangaSortBean) -> Unit,\n) {\n    Scaffold(\n        modifier = Modifier.fillMaxWidth(),\n        topBar = {\n            Column {\n                TopAppBar(\n                    title = {\n                        Text(text = title)\n                    }\n                )\n                HorizontalDivider()\n            }\n        }\n    ) {\n        LazyColumn(\n            modifier = Modifier\n                .padding(24.dp),\n            contentPadding = it\n        ) {\n            itemsIndexed(list) { index, item ->\n                ExploreFilterBottomSheetItem(\n                    msb = item,\n                    isSelected = sortBean?.pathWord == item.pathWord,\n                    onSelected = onSelected\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun ExploreFilterBottomSheetItem(\n    modifier: Modifier = Modifier,\n    msb: MangaSortBean,\n    isSelected: Boolean,\n    onSelected: (MangaSortBean) -> Unit,\n) {\n\n    Column(\n        modifier = modifier\n            .clip(shape = CircleShape)\n            .selectable(\n                isSelected,\n                onClick = { onSelected(msb) },\n                role = Role.Button\n            )\n            .background(\n                if (isSelected) MaterialTheme.colorScheme.primary.copy(.22f)\n                else Color.Transparent,\n            )\n            .fillMaxWidth()\n    ) {\n        Row(\n            modifier = Modifier\n                .height(height = 56.dp)\n                .padding(\n                    start = dimensionAttribute(attrResId = android.R.attr.listPreferredItemPaddingStart),\n                    end = dimensionAttribute(attrResId = android.R.attr.listPreferredItemPaddingEnd)\n                ),\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            AnimatedVisibility(\n                visible = isSelected,\n                enter = expandHorizontally(expandFrom = Alignment.Start),\n                exit = shrinkHorizontally(shrinkTowards = Alignment.Start)\n            ) {\n                Icon(\n                    painter = painterResource(id = R.drawable.baseline_done_24),\n                    contentDescription = null,\n                    modifier = Modifier\n                        .padding(end = 16.dp)\n                )\n                Spacer(modifier = Modifier.width(width = dimensionAttribute(attrResId = android.R.attr.listPreferredItemPaddingStart)))\n            }\n            Text(\n                text = msb.pathName,\n                modifier = Modifier.weight(1f),\n                style = MaterialTheme.typography.titleSmall\n            )\n        }\n    }\n}\n\nprivate fun roundedCornerShapeWith(isLast: Boolean, isTop: Boolean, size: Dp): RoundedCornerShape {\n    return when {\n        isTop -> RoundedCornerShape(\n            topStart = size,\n            topEnd = size,\n            bottomEnd = 0.dp,\n            bottomStart = 0.dp\n        )\n\n        isLast -> RoundedCornerShape(\n            topStart = 0.dp,\n            topEnd = 0.dp,\n            bottomEnd = size,\n            bottomStart = size\n        )\n\n        else -> RoundedCornerShape(0.dp)\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/explore/ExploreMangaFilter.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.explore\n\nimport androidx.compose.animation.animateContentSize\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.FilterChip\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.json.MangaSortJson\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun ExploreFilter(\n    modifier: Modifier = Modifier,\n    showList: MutableMap<MangaSortJson, MangaSortBean?>,\n    onThemeClick: () -> Unit,\n    onOrderClick: () -> Unit,\n    onTopClick: () -> Unit,\n) {\n    Column(\n        modifier = modifier\n            .fillMaxWidth()\n            .animateContentSize(),\n    ) {\n        Row(\n            horizontalArrangement = Arrangement.spacedBy(16.dp)\n        ) {\n            FilterChip(\n                onClick = onOrderClick,\n                modifier = Modifier.animateContentSize(),\n                label = {\n                    Text(\n                        text = showList[MangaSortJson.ORDER]?.pathName\n                            ?: stringResource(id = R.string.order)\n                    )\n                },\n                selected = showList[MangaSortJson.ORDER] != null,\n                trailingIcon = {\n                    Icon(\n                        painter = painterResource(id = com.google.android.material.R.drawable.mtrl_ic_arrow_drop_down),\n                        contentDescription = null\n                    )\n                }\n            )\n            FilterChip(\n                onClick = onTopClick,\n                modifier = Modifier.animateContentSize(),\n                label = {\n                    Text(\n                        text = showList[MangaSortJson.PATH]?.pathName\n                            ?: stringResource(id = R.string.top)\n                    )\n                },\n                trailingIcon = {\n                    Icon(\n                        painter = painterResource(id = com.google.android.material.R.drawable.mtrl_ic_arrow_drop_down),\n                        contentDescription = null\n                    )\n                },\n                selected = showList[MangaSortJson.PATH] != null\n            )\n            FilterChip(\n                onClick = onThemeClick,\n                modifier = Modifier.animateContentSize(),\n                label = {\n                    Text(\n                        text = showList[MangaSortJson.THEME]?.pathName\n                            ?: stringResource(id = R.string.theme)\n                    )\n                },\n                trailingIcon = {\n                    Icon(\n                        painter = painterResource(id = com.google.android.material.R.drawable.mtrl_ic_arrow_drop_down),\n                        contentDescription = null\n                    )\n                },\n                selected = showList[MangaSortJson.THEME] != null\n            )\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/explore/ExploreScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.explore\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.ModalBottomSheet\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.SheetValue\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.rememberModalBottomSheetState\nimport androidx.compose.material3.rememberTopAppBarState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateMapOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.LoadState\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport androidx.paging.compose.itemContentType\nimport androidx.paging.compose.itemKey\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.finished.Item\nimport com.shicheeng.copymanga.json.MangaSortJson\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.ui.screen.compoents.pullrefresh.SwipeRefresh\nimport com.shicheeng.copymanga.ui.screen.compoents.pullrefresh.rememberSwipeRefreshState\nimport com.shicheeng.copymanga.ui.screen.compoents.withAppBarColor\nimport com.shicheeng.copymanga.ui.theme.ElevationTokens\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.viewmodel.ExploreMangaViewModel\n\n@OptIn(\n    ExperimentalMaterial3Api::class,\n    ExperimentalFoundationApi::class\n)\n@Composable\nfun ExploreScreen(\n    top: String?,\n    theme: String?,\n    order: String?,\n    exploreMangaViewModel: ExploreMangaViewModel = hiltViewModel(),\n    onNavigationIconClick: (() -> Unit)? = null,\n    onItemClick: (Item) -> Unit,\n) {\n\n    val sortLoadingState by exploreMangaViewModel.uiState.collectAsState()\n    val mangaList = exploreMangaViewModel.loadFilterResult.collectAsLazyPagingItems()\n    val bottomWhatToShow by exploreMangaViewModel.showBottomSheet.collectAsState()\n    val coroutineScope = rememberCoroutineScope()\n\n    if (sortLoadingState is UIState.Loading) {\n        LoadingScreen()\n        return\n    }\n\n    if (sortLoadingState is UIState.Error<*>) {\n        ErrorScreen(\n            errorMessage = (sortLoadingState as UIState.Error<*>).errorMessage.message\n                ?: stringResource(id = R.string.error)\n        ) {\n            exploreMangaViewModel.loadData()\n        }\n        return\n    }\n\n    val successData = sortLoadingState as UIState.Success\n    if (top != null || order != null || theme != null) {\n        LaunchedEffect(Unit) {\n            exploreMangaViewModel.filterOn(\n                order, theme, top\n            )\n        }\n    }\n    var isExpand by remember { mutableStateOf(false) }\n    val layoutDirection = LocalLayoutDirection.current\n    val sheetState = rememberModalBottomSheetState(\n        skipPartiallyExpanded = false\n    )\n    val pullRefreshState = rememberSwipeRefreshState(\n        isRefreshing = mangaList.loadState.refresh is LoadState.Loading,\n    )\n    val (orderSave, onOrderSave) = rememberSaveable {\n        mutableStateOf<String?>(null)\n    }\n    val (topSave, onTopSave) = rememberSaveable {\n        mutableStateOf<String?>(null)\n    }\n    val (themeSave, onThemeSave) = rememberSaveable {\n        mutableStateOf<String?>(null)\n    }\n    val hashMap = remember {\n        mutableStateMapOf(\n            MangaSortJson.ORDER to MangaSortJson.order.find { x -> x.pathWord == orderSave || x.pathWord == order },\n            MangaSortJson.THEME to successData.content.find { x -> x.pathWord == themeSave || x.pathWord == theme },\n            MangaSortJson.PATH to MangaSortJson.topPath.find { x -> x.pathWord == topSave || x.pathWord == top },\n        )\n    }\n    val topAppBarState = rememberTopAppBarState()\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(state = topAppBarState)\n\n\n    Scaffold(\n        topBar = {\n            Column {\n                TopAppBar(\n                    title = {\n                        Text(text = stringResource(id = R.string.explore))\n                    },\n                    navigationIcon = {\n                        if (onNavigationIconClick != null) {\n                            PlainButton(\n                                id = R.string.back_to_up,\n                                drawableRes = R.drawable.ic_arrow_back,\n                                onButtonClick = onNavigationIconClick\n                            )\n                        }\n                    },\n                    scrollBehavior = topAppBarScrollBehavior\n                )\n                ExploreFilter(\n                    showList = hashMap,\n                    onThemeClick = {\n                        exploreMangaViewModel.showThemeFilterList()\n                        isExpand = true\n                    },\n                    onOrderClick = {\n                        exploreMangaViewModel.showOrderFilterList()\n                        isExpand = true\n                    },\n                    modifier = Modifier\n                        .background(withAppBarColor(topAppBarState = topAppBarState))\n                        .padding(horizontal = 16.dp)\n                ) {\n                    exploreMangaViewModel.showTopFilterList()\n                    isExpand = true\n                }\n                HorizontalDivider()\n            }\n        },\n    ) { paddingValues ->\n        SwipeRefresh(\n            modifier = Modifier.fillMaxSize(),\n            state = pullRefreshState,\n            onRefresh = mangaList::refresh,\n            indicatorPadding = paddingValues\n        ) {\n            LazyVerticalGrid(\n                columns = GridCells.Fixed(3),\n                contentPadding = paddingValues.copy(\n                    layoutDirection = layoutDirection,\n                    bottom = paddingValues.calculateBottomPadding(),\n                    start = 16.dp,\n                    end = 16.dp,\n                    top = paddingValues.calculateTopPadding() + 16.dp\n                ),\n                modifier = Modifier\n                    .fillMaxSize()\n                    .nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),\n                horizontalArrangement = Arrangement.spacedBy(16.dp),\n                verticalArrangement = Arrangement.spacedBy(16.dp)\n            ) {\n                items(\n                    mangaList.itemCount,\n                    key = mangaList.itemKey(),\n                    contentType = mangaList.itemContentType()\n                ) { itemIndex ->\n                    mangaList[itemIndex]?.let { item ->\n                        ExploreItem(\n                            item = item,\n                            onItemClick = onItemClick,\n                            modifier = Modifier.animateItemPlacement()\n                        )\n                    }\n                }\n                pagingLoadingIndication(\n                    loadState = mangaList.loadState.append\n                ) {\n                    mangaList.retry()\n                }\n            }\n\n        }\n    }\n\n    val cornerShape by animateDpAsState(\n        targetValue = if (sheetState.currentValue == SheetValue.Expanded) {\n            0.dp\n        } else {\n            28.0.dp\n        },\n        label = \"DP_OF_SHEET\"\n    )\n    if (isExpand) {\n        ModalBottomSheet(\n            onDismissRequest = { isExpand = false },\n            sheetState = sheetState,\n            windowInsets = WindowInsets(0, 0, 0, 0),\n            modifier = Modifier.zIndex(1f),\n            shape = RoundedCornerShape(\n                topEnd = cornerShape,\n                topStart = cornerShape,\n                bottomStart = 0.dp,\n                bottomEnd = 0.dp\n            ),\n            tonalElevation = ElevationTokens.Level2\n        ) {\n            when (bottomWhatToShow) {\n                MangaSortJson.ORDER -> {\n                    ExploreFilterBottomSheet(\n                        list = MangaSortJson.order,\n                        sortBean = hashMap[MangaSortJson.ORDER],\n                        title = stringResource(id = R.string.order)\n                    ) {\n                        hashMap[MangaSortJson.ORDER] = it\n                        exploreMangaViewModel.filterOn(\n                            theme = hashMap[MangaSortJson.THEME]?.pathWord,\n                            top = hashMap[MangaSortJson.PATH]?.pathWord,\n                            order = it.pathWord.ifBlank { null }\n                        )\n                        onOrderSave(it.pathWord)\n                    }\n                }\n\n                MangaSortJson.THEME -> {\n                    ExploreFilterBottomSheet(\n                        list = successData.content,\n                        sortBean = hashMap[MangaSortJson.THEME],\n                        title = stringResource(id = R.string.theme)\n                    ) {\n                        hashMap[MangaSortJson.THEME] = it\n                        exploreMangaViewModel.filterOn(\n                            theme = it.pathWord.ifBlank { null },\n                            top = hashMap[MangaSortJson.PATH]?.pathWord,\n                            order = hashMap[MangaSortJson.ORDER]?.pathWord\n                        )\n                        onThemeSave(it.pathWord)\n                    }\n                }\n\n                MangaSortJson.PATH -> {\n                    ExploreFilterBottomSheet(\n                        list = MangaSortJson.topPath,\n                        sortBean = hashMap[MangaSortJson.PATH],\n                        title = stringResource(id = R.string.top),\n                        onSelected = {\n                            hashMap[MangaSortJson.PATH] = it\n                            exploreMangaViewModel.filterOn(\n                                theme = hashMap[MangaSortJson.THEME]?.pathWord,\n                                top = it.pathWord.ifBlank { null },\n                                order = hashMap[MangaSortJson.ORDER]?.pathWord\n                            )\n                            onTopSave(it.pathWord)\n                        }\n                    )\n                }\n            }\n        }\n    }\n\n    BackHandler(enabled = isExpand) {\n        isExpand = false\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/BannerComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.wrapContentHeight\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshotFlow\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\nimport com.google.accompanist.pager.HorizontalPagerIndicator\nimport com.shicheeng.copymanga.data.DataBannerBean\nimport com.shicheeng.copymanga.util.click\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.yield\n\n\n/**\n * 按照官方的例子抄的\n */\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\nfun Banner(\n    modifier: Modifier = Modifier,\n    list: List<DataBannerBean>,\n    click: (DataBannerBean) -> Unit,\n) {\n    val pageCount = list.size\n    val pageStateBanner = rememberBannerState(initialCount = 0, pagerCount = { pageCount })\n\n    fun pageMapper(index: Int): Int = (index - 0) floorMod pageCount\n\n    var underDragging by remember { mutableStateOf(false) }\n\n    LaunchedEffect(key1 = Unit) {\n        pageStateBanner.interactionSource.interactions.collect { interaction ->\n            when (interaction) {\n                is PressInteraction.Press -> underDragging = true\n                is PressInteraction.Release -> underDragging = false\n                is PressInteraction.Cancel -> underDragging = false\n                is DragInteraction.Start -> underDragging = true\n                is DragInteraction.Stop -> underDragging = false\n                is DragInteraction.Cancel -> underDragging = false\n            }\n        }\n    }\n\n    Box(\n        modifier = modifier.fillMaxWidth()\n    ) {\n        HorizontalPager(\n            state = pageStateBanner,\n            modifier = Modifier\n                .fillMaxWidth()\n                .wrapContentHeight()\n        ) { index ->\n            val page = pageMapper(index)\n            BannerItem(dataBannerBean = list[page], bannerClick = click)\n        }\n        HorizontalPagerIndicator(\n            pagerState = pageStateBanner,\n            pageCount = pageCount,\n            modifier = Modifier.align(Alignment.BottomCenter),\n            pageIndexMapping = ::pageMapper\n        )\n    }\n\n    AutoScrollSideEffect(\n        autoScrollDurationMillis = 5000L,\n        pageCount = pageCount,\n        pagerState = pageStateBanner,\n        doAutoScroll = underDragging.not()\n    )\n\n}\n\n@Composable\nfun BannerItem(\n    dataBannerBean: DataBannerBean,\n    bannerClick: (DataBannerBean) -> Unit,\n) {\n    val colors = listOf(\n        MaterialTheme.colorScheme.surface,\n        Color.Transparent,\n        Color.Transparent,\n        Color.Transparent,\n        MaterialTheme.colorScheme.surface\n    )\n    val textBackgroundColor = MaterialTheme.colorScheme.surface\n    Box(\n        modifier = Modifier\n            .fillMaxWidth()\n            .fillMaxHeight()\n            .click { bannerClick.invoke(dataBannerBean) }\n    ) {\n        AsyncImage(\n            model = dataBannerBean.bannerImageUrl,\n            contentDescription = null,\n            contentScale = ContentScale.Crop,\n            placeholder = ColorPainter(MaterialTheme.colorScheme.surface),\n            modifier = Modifier\n                .matchParentSize()\n                .drawWithContent {\n                    drawContent()\n                    drawRect(brush = Brush.verticalGradient(colors))\n                }\n        )\n        Column(\n            modifier = Modifier\n                .fillMaxWidth()\n                .align(Alignment.BottomStart)\n                .padding(bottom = 16.dp, start = 16.dp, end = 16.dp)\n        ) {\n            Text(\n                text = dataBannerBean.bannerBrief,\n                modifier = Modifier\n                    .drawWithContent {\n                        drawRect(color = textBackgroundColor)\n                        drawContent()\n                    }\n                    .padding(2.dp),\n                color = MaterialTheme.colorScheme.onSurface\n            )\n        }\n    }\n}\n\n/**\n * 使用新的自动滑动方法。\n */\n@Composable\nprivate fun AutoScrollSideEffect(\n    autoScrollDurationMillis: Long,\n    pageCount: Int,\n    pagerState: BannerState,\n    doAutoScroll: Boolean,\n    onAutoScrollChange: (isAutoScrollActive: Boolean) -> Unit = {},\n) {\n    if (autoScrollDurationMillis == Long.MAX_VALUE || autoScrollDurationMillis < 0) {\n        return\n    }\n\n    // Needed to ensure that the code within LaunchedEffect receives updates to the itemCount.\n    val updatedItemCount by rememberUpdatedState(newValue = pageCount)\n    if (doAutoScroll) {\n        LaunchedEffect(pagerState) {\n            while (true) {\n                yield()\n                delay(autoScrollDurationMillis)\n                if (pagerState.activePauseHandlesCount > 0) {\n                    snapshotFlow { pagerState.activePauseHandlesCount }\n                        .first { pauseHandleCount -> pauseHandleCount == 0 }\n                }\n                pagerState.moveToNextItem(updatedItemCount)\n            }\n        }\n    }\n    onAutoScrollChange(doAutoScroll)\n}\n\nprivate infix fun Int.floorMod(other: Int): Int = when (other) {\n    0 -> this\n    else -> this - floorDiv(other) * other\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/BannerState.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.pager.PagerState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport java.lang.Math.floorMod\n\n@OptIn(ExperimentalFoundationApi::class)\nclass BannerState(\n    initialActiveItemIndex: Int = 0,\n    updatedPageCount: () -> Int,\n) : PagerState() {\n    internal var activePauseHandlesCount by mutableIntStateOf(0)\n\n    /**\n     * The index of the item that is currently displayed by the carousel\n     */\n    var activeItemIndex by mutableIntStateOf(initialActiveItemIndex)\n        internal set\n\n    var pagerCountState = mutableStateOf(updatedPageCount)\n\n    internal var isMovingBackward = false\n        private set\n\n    override val pageCount: Int\n        get() = pagerCountState.value.invoke()\n\n    fun moveToPreviousItem(itemCount: Int) {\n        // No items available for carousel\n        if (itemCount == 0) return\n\n        isMovingBackward = true\n\n        // Go to previous item\n        activeItemIndex = floorMod(activeItemIndex - 1, itemCount)\n    }\n\n    internal suspend fun moveToNextItem(itemCount: Int) {\n        // No items available for carousel\n        if (itemCount == 0) return\n\n        isMovingBackward = false\n\n        // Go to next item\n        activeItemIndex = floorMod(activeItemIndex + 1, itemCount)\n        animateScrollToPage(activeItemIndex)\n    }\n\n    companion object {\n        /**\n         * The default [Saver] implementation for [Banner].\n         */\n        val Saver: Saver<BannerState, *> = Saver(\n            save = { it.activeItemIndex }\n        ) { BannerState { it } }\n    }\n}\n\n@Composable\nfun rememberBannerState(\n    initialCount: Int,\n    pagerCount: () -> Int,\n) = rememberSaveable(saver = BannerState.Saver) {\n    BannerState(\n        updatedPageCount = pagerCount,\n        initialActiveItemIndex = initialCount\n    ).apply {\n        pagerCountState.value = pagerCount\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/HomeComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TextButton\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.ListBeanManga\nimport com.shicheeng.copymanga.ui.screen.compoents.MangaCover\n\n\n@Composable\nfun HomeBarColumn(\n    title: String,\n    list: List<ListBeanManga>,\n    onHeaderLineClick: () -> Unit,\n    onEachClick: (ListBeanManga) -> Unit,\n) {\n    Column(\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        HomeRowHeaderLine(title = title, click = onHeaderLineClick)\n        LazyRow(\n            modifier = Modifier.fillMaxWidth(),\n            contentPadding = PaddingValues(all = 16.dp),\n            horizontalArrangement = Arrangement.spacedBy(16.dp)\n        ) {\n            items(list) {\n                HomeBarColumnCover(listBeanManga = it, click = onEachClick)\n            }\n        }\n    }\n}\n\n@Composable\nfun HomeRowHeaderLine(\n    title: String,\n    click: () -> Unit,\n) {\n    Row(\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(horizontal = 16.dp),\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        Text(\n            text = title,\n            style = MaterialTheme.typography.titleLarge,\n            modifier = Modifier.weight(1f)\n        )\n        TextButton(\n            modifier = Modifier,\n            onClick = click,\n        ) {\n            Text(\n                text = stringResource(R.string.see_all),\n                modifier = Modifier.align(Alignment.CenterVertically)\n            )\n        }\n    }\n}\n\n@Preview(showBackground = true)\n@Composable\nfun HomeRowHeaderLinePriview() {\n    HomeRowHeaderLine(title = \"haokande\") {\n\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun HomeBarColumnCover(\n    listBeanManga: ListBeanManga,\n    click: (ListBeanManga) -> Unit,\n) {\n    Card(\n        onClick = { click.invoke(listBeanManga) }\n    ) {\n        Column(\n            modifier = Modifier\n                .width(IntrinsicSize.Min)\n                .padding(bottom = 4.dp)\n        ) {\n            MangaCover.Big(\n                url = listBeanManga.urlCoverManga,\n                shape = MaterialTheme.shapes.medium\n            )\n            Text(\n                text = listBeanManga.nameManga,\n                style = MaterialTheme.typography.titleSmall,\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis\n            )\n            Text(\n                text = listBeanManga.authorManga,\n                style = MaterialTheme.typography.bodySmall,\n                maxLines = 1,\n                color = MaterialTheme.colorScheme.onSurfaceVariant,\n                overflow = TextOverflow.Ellipsis\n            )\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/HomeLeaderBoard.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Tab\nimport androidx.compose.material3.TabRow\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MainPageDataModel\nimport com.shicheeng.copymanga.data.MangaRankMiniModel\nimport com.shicheeng.copymanga.ui.screen.compoents.MangaCover\n\n\n@OptIn(ExperimentalFoundationApi::class)\nfun LazyListScope.miniLeaderBoard(\n    selectedTabIndex: Int,\n    onTabClick: (Int) -> Unit,\n    rankList: List<String>,\n    mainPageDataModel: MainPageDataModel,\n    onHeaderLineClick: () -> Unit,\n    onRankItemClick: (MangaRankMiniModel) -> Unit,\n) {\n    item(\n        key = HomeListKey.RANK,\n        contentType = HomeListKey.RANK\n    ) {\n        HomeRowHeaderLine(\n            title = stringResource(id = R.string.rank_mini),\n            click = onHeaderLineClick\n        )\n    }\n\n    stickyHeader {\n        TabRow(selectedTabIndex = selectedTabIndex) {\n            rankList.forEachIndexed { index, s ->\n                Tab(\n                    selected = index == selectedTabIndex,\n                    onClick = { onTabClick.invoke(index) },\n                    text = {\n                        Text(text = s)\n                    }\n                )\n            }\n        }\n    }\n    when (selectedTabIndex) {\n        0 -> {\n            items(mainPageDataModel.listRankDay, key = { it.name }) {\n                MiniRankItem(\n                    miniModel = it,\n                    onRankItemClick = onRankItemClick,\n                    modifier = Modifier.animateItemPlacement()\n                )\n            }\n        }\n\n        1 -> {\n            items(\n                items = mainPageDataModel.listRankWeek,\n                key = {\n                    it.name\n                }\n            ) {\n                MiniRankItem(\n                    miniModel = it,\n                    onRankItemClick = onRankItemClick,\n                    modifier = Modifier.animateItemPlacement()\n                )\n            }\n        }\n\n        2 -> {\n            items(\n                items = mainPageDataModel.listRankMonth,\n                key = {\n                    it.name\n                }\n            ) {\n                MiniRankItem(\n                    miniModel = it,\n                    onRankItemClick = onRankItemClick,\n                    modifier = Modifier.animateItemPlacement()\n                )\n            }\n        }\n    }\n\n}\n\n\n@Composable\nfun MiniRankItem(\n    modifier: Modifier = Modifier,\n    miniModel: MangaRankMiniModel,\n    onRankItemClick: (MangaRankMiniModel) -> Unit,\n) {\n    Row(\n        modifier = modifier\n            .clickable { onRankItemClick.invoke(miniModel) }\n            .fillMaxWidth()\n            .padding(horizontal = 16.dp, vertical = 8.dp)\n    ) {\n        MangaCover.ExtraSmall(\n            url = miniModel.urlCover,\n        )\n        Column(\n            modifier = Modifier\n                .padding(start = 8.dp, end = 8.dp)\n                .weight(1f)\n        ) {\n            Text(\n                text = miniModel.name,\n                style = MaterialTheme.typography.titleMedium,\n                fontWeight = FontWeight.Bold\n            )\n            Text(\n                text = miniModel.author,\n                style = MaterialTheme.typography.bodyMedium,\n                modifier = Modifier.padding(top = 4.dp)\n            )\n            Row {\n                Icon(\n                    painter = painterResource(id = R.drawable.ic_trend_up),\n                    contentDescription = stringResource(R.string.trend_up),\n                    modifier = Modifier.size(20.dp),\n                    tint = MaterialTheme.colorScheme.primary\n                )\n                Text(\n                    text = miniModel.riseHot,\n                    style = MaterialTheme.typography.bodyMedium,\n                    modifier = Modifier.padding(start = 4.dp)\n                )\n            }\n            Text(\n                text = miniModel.popular,\n                style = MaterialTheme.typography.bodySmall,\n                modifier = Modifier.padding(top = 2.dp)\n            )\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/HomeListKey.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home\n\nenum class HomeListKey {\n    BANNER, RANK, RECOMMEND, HOT, NEWEST, FINISH, TOPICS_RECOMMEND\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/HomeScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MainTopicDataModel\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.viewmodel.HomeViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun HomeScreen(\n    homeViewModel: HomeViewModel = hiltViewModel(),\n    onUUid: (String) -> Unit,\n    onSearchButtonClick: () -> Unit,\n    onSettingButtonClick: () -> Unit,\n    onRecommendHeaderLineClick: () -> Unit,\n    onRankHeaderLineClick: () -> Unit,\n    onHotHeaderLineClick: () -> Unit,\n    onNewestHeaderLineClick: () -> Unit,\n    onFinishHeaderLineClick: () -> Unit,\n    onTopicCardClick: (MainTopicDataModel) -> Unit,\n    onTopicsClickLineClick: () -> Unit,\n) {\n\n    val uiState by homeViewModel.uiState.collectAsState()\n\n    if (uiState is UIState.Loading) {\n        LoadingScreen()\n        return\n    }\n\n    if (uiState is UIState.Error<*>) {\n        ErrorScreen(\n            errorMessage = (uiState as UIState.Error<*>).errorMessage.message\n                ?: stringResource(id = R.string.error),\n            secondaryText = stringResource(id = R.string.setting),\n            onTry = {\n                homeViewModel.loadData()\n            },\n            onSecondaryClick = onSettingButtonClick\n        )\n        return\n    }\n\n    val successUIState = uiState as UIState.Success\n    val layoutDirection = LocalLayoutDirection.current\n    val listRank = listOf(\n        stringResource(id = R.string.day_rank),\n        stringResource(id = R.string.week_rank),\n        stringResource(id = R.string.month_rank)\n    )\n    var selectTabIndex by remember {\n        mutableIntStateOf(0)\n    }\n    val lazyListState = rememberLazyListState()\n\n    Scaffold(\n        modifier = Modifier.fillMaxSize(),\n        topBar = {\n            val firstVisibleItemIndex by remember {\n                derivedStateOf { lazyListState.firstVisibleItemIndex }\n            }\n            val firstVisibleItemScrollOffset by remember {\n                derivedStateOf { lazyListState.firstVisibleItemScrollOffset }\n            }\n            val animatedTitleAlpha by animateFloatAsState(\n                if (firstVisibleItemIndex > 0) 1f else 0f, label = \"animated_title_alpha\",\n            )\n            val animatedBgAlpha by animateFloatAsState(\n                if (firstVisibleItemIndex > 0 || firstVisibleItemScrollOffset > 0) 1f else 0f,\n                label = \"animated_background_alpha\",\n            )\n            TopAppBar(\n                title = {\n                    Text(\n                        text = stringResource(id = R.string.app_name),\n                        modifier = Modifier.alpha(animatedTitleAlpha)\n                    )\n                },\n                colors = TopAppBarDefaults.topAppBarColors(\n                    containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp)\n                        .copy(alpha = animatedBgAlpha)\n                ),\n                actions = {\n                    PlainButton(\n                        id = androidx.appcompat.R.string.search_menu_title,\n                        drawableRes = R.drawable.ic_manga_search,\n                        onButtonClick = onSearchButtonClick\n                    )\n                    PlainButton(\n                        id = R.string.setting,\n                        drawableRes = R.drawable.ic_setting_outline,\n                        onButtonClick = onSettingButtonClick\n                    )\n                }\n            )\n        }\n    ) { padding ->\n        LazyColumn(\n            modifier = Modifier.fillMaxSize(),\n            contentPadding = padding.copy(\n                layoutDirection = layoutDirection,\n                bottom = padding.calculateBottomPadding() ,\n                top = 0.dp\n            ),\n            state = lazyListState\n        ) {\n            item(\n                key = HomeListKey.BANNER,\n                contentType = HomeListKey.BANNER\n            ) {\n                Banner(\n                    list = successUIState.content.listBanner,\n                    modifier = Modifier.height(250.dp)\n                ) { model ->\n                    onUUid.invoke(model.uuidManga)\n                }\n            }\n            item(\n                key = HomeListKey.RECOMMEND,\n                contentType = HomeListKey.RECOMMEND\n            ) {\n                HomeBarColumn(\n                    title = stringResource(id = R.string.recommend),\n                    list = successUIState.content.listRecommend,\n                    onHeaderLineClick = onRecommendHeaderLineClick\n                ) {\n                    onUUid.invoke(it.pathWordManga)\n                }\n            }\n            miniLeaderBoard(\n                selectedTabIndex = selectTabIndex,\n                onTabClick = { index ->\n                    selectTabIndex = index\n                },\n                rankList = listRank,\n                mainPageDataModel = successUIState.content,\n                onHeaderLineClick = onRankHeaderLineClick\n            ) {\n                onUUid.invoke(it.pathWord)\n            }\n            item(\n                key = HomeListKey.HOT,\n                contentType = HomeListKey.HOT\n            ) {\n                HomeBarColumn(\n                    title = stringResource(id = R.string.hot_manga),\n                    list = successUIState.content.listHot,\n                    onHeaderLineClick = onHotHeaderLineClick\n                ) {\n                    onUUid.invoke(it.pathWordManga)\n                }\n            }\n            item(\n                key = HomeListKey.NEWEST,\n                contentType = HomeListKey.NEWEST\n            ) {\n                HomeBarColumn(\n                    title = stringResource(id = R.string.new_manga),\n                    list = successUIState.content.listNewest,\n                    onHeaderLineClick = onNewestHeaderLineClick\n                ) {\n                    onUUid.invoke(it.pathWordManga)\n                }\n            }\n            item(\n                key = HomeListKey.FINISH,\n                contentType = HomeListKey.FINISH\n            ) {\n                HomeBarColumn(\n                    title = stringResource(id = R.string.finish_manga),\n                    list = successUIState.content.listFinished,\n                    onHeaderLineClick = onFinishHeaderLineClick\n                ) {\n                    onUUid.invoke(it.pathWordManga)\n                }\n            }\n            item(\n                key = HomeListKey.TOPICS_RECOMMEND,\n                contentType = HomeListKey.TOPICS_RECOMMEND\n            ) {\n                HomePageTopicRow(\n                    list = successUIState.content.topicList,\n                    onTopicBarClick = onTopicsClickLineClick,\n                    onItemClick = onTopicCardClick\n                )\n            }\n        }\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/HomeTopicCard.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.wrapContentHeight\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedCard\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MainTopicDataModel\n\n@Composable\nfun HomePageTopicRow(\n    list: List<MainTopicDataModel>,\n    onTopicBarClick: () -> Unit,\n    onItemClick: (MainTopicDataModel) -> Unit,\n) {\n    val lazyState = rememberLazyListState()\n    Column {\n        HomeRowHeaderLine(title = stringResource(R.string.topic), click = onTopicBarClick)\n        LazyRow(\n            modifier = Modifier.fillMaxWidth(),\n            contentPadding = PaddingValues(all = 16.dp),\n            horizontalArrangement = Arrangement.spacedBy(16.dp),\n            state = lazyState\n        ) {\n            items(list) {\n                HomePageTopicCard(\n                    title = it.name,\n                    supportedText = it.brief,\n                    subText = it.period,\n                    imageUrl = it.coverUrl,\n                    modifier = Modifier.width(320.dp),\n                    maxSupportedTextLine = 3,\n                    isTitleMaxTwo = true\n                ) {\n                    onItemClick(it)\n                }\n            }\n        }\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun HomePageTopicCard(\n    modifier: Modifier = Modifier,\n    title: String,\n    supportedText: String,\n    subText: String,\n    imageUrl: String?,\n    maxSupportedTextLine: Int = Int.MAX_VALUE,\n    isTitleMaxTwo: Boolean = false,\n    onClickAction: () -> Unit,\n) {\n    OutlinedCard(\n        modifier = modifier,\n        onClick = onClickAction\n    ) {\n        Column(\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(16.dp)\n        ) {\n            Text(\n                text = title,\n                style = MaterialTheme.typography.headlineSmall,\n                color = MaterialTheme.colorScheme.onSurface,\n                maxLines = if (isTitleMaxTwo) 2 else Int.MAX_VALUE,\n                overflow = TextOverflow.Ellipsis\n            )\n            Text(\n                text = subText,\n                style = MaterialTheme.typography.titleMedium,\n                color = MaterialTheme.colorScheme.onSurface,\n                modifier = Modifier.padding(top = 16.dp)\n            )\n            Text(\n                text = supportedText,\n                color = MaterialTheme.colorScheme.onSurfaceVariant,\n                modifier = Modifier.padding(top = 8.dp),\n                maxLines = maxSupportedTextLine,\n                overflow = TextOverflow.Ellipsis\n            )\n            AsyncImage(\n                model = imageUrl,\n                contentDescription = null,\n                placeholder = ColorPainter(color = MaterialTheme.colorScheme.secondary),\n                modifier = Modifier\n                    .wrapContentHeight()\n                    .fillMaxWidth()\n                    .padding(top = 16.dp, bottom = 16.dp)\n                    .clip(MaterialTheme.shapes.medium)\n                    .aspectRatio(5f / 2f),\n                contentScale = ContentScale.Crop\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/search/Search.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home.search\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.ListItem\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.util.copyComposable\nimport com.shicheeng.copymanga.viewmodel.SearchViewModel\n\n@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)\n@Composable\nfun SearchScreen(\n    searchViewModel: SearchViewModel = hiltViewModel(),\n    onSearch: (String) -> Unit,\n    onBack: () -> Unit,\n) {\n\n    val (searchKeyWord, onSaveKeyWord) = rememberSaveable { mutableStateOf(\"\") }\n    val historyWords by searchViewModel.searchedHistoryWord.collectAsState()\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n\n    Scaffold(\n        topBar = {\n            FullScreenSearchViewHeader(\n                value = searchKeyWord,\n                valueChange = {\n                    onSaveKeyWord(it)\n                    searchViewModel.upWord(it)\n                },\n                onSearch = {\n                    onSearch(it)\n                    searchViewModel.saveSearchWord(it)\n                },\n                onBackClick = onBack,\n                topAppBarScrollBehavior = topAppBarScrollBehavior\n            ) {\n                onSaveKeyWord(\"\")\n                searchViewModel.upWord(\"\")\n            }\n        }\n    ) { paddingValue ->\n        LazyColumn(\n            modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),\n            contentPadding = paddingValue.copyComposable(\n                top = 16.dp + paddingValue.calculateTopPadding()\n            )\n        ) {\n            items(\n                items = historyWords,\n                key = { it }\n            ) {\n                ListItem(\n                    headlineContent = {\n                        Text(text = it)\n                    },\n                    leadingContent = {\n                        Icon(\n                            painter = painterResource(id = R.drawable.baseline_history_24),\n                            contentDescription = null\n                        )\n                    },\n                    modifier = Modifier\n                        .animateItemPlacement()\n                        .clickable {\n                            onSearch(it)\n                            searchViewModel.saveSearchWord(it)\n                        }\n                )\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/home/search/SearchComponent.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.home.search\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.text.BasicTextField\nimport androidx.compose.foundation.text.KeyboardActions\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarScrollBehavior\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.input.ImeAction\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport soup.compose.material.motion.MaterialFade\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun FullScreenSearchViewHeader(\n    modifier: Modifier = Modifier,\n    topAppBarScrollBehavior: TopAppBarScrollBehavior,\n    value: String,\n    valueChange: (String) -> Unit,\n    onSearch: (String) -> Unit,\n    onBackClick: () -> Unit,\n    onClearClick: () -> Unit,\n) {\n    Column(\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        TopAppBar(\n            modifier = modifier.fillMaxWidth(),\n            title = {\n                BasicTextField(\n                    value = value,\n                    onValueChange = valueChange,\n                    singleLine = true,\n                    modifier = Modifier,\n                    textStyle = MaterialTheme.typography.bodyLarge.copy(\n                        color = MaterialTheme.colorScheme.onSurface\n                    ),\n                    keyboardActions = KeyboardActions(\n                        onSearch = {\n                            onSearch(value)\n                        }\n                    ),\n                    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),\n                    cursorBrush = SolidColor(value = MaterialTheme.colorScheme.secondary)\n                ) { innerTextField ->\n                    Box(\n                        modifier = Modifier.fillMaxWidth(),\n                        contentAlignment = Alignment.CenterStart\n                    ) {\n                        innerTextField()\n                        MaterialFade(visible = value.isBlank()) {\n                            Text(\n                                text = stringResource(id = R.string.search_text),\n                                style = MaterialTheme.typography.bodyLarge,\n                                color = MaterialTheme.colorScheme.onSurfaceVariant,\n                            )\n                        }\n                    }\n                }\n            },\n            navigationIcon = {\n                PlainButton(\n                    id = R.string.back_to_up,\n                    drawableRes = R.drawable.ic_arrow_back,\n                    onButtonClick = onBackClick\n                )\n            },\n            actions = {\n                MaterialFade(visible = value.isNotEmpty()) {\n                    PlainButton(\n                        id = com.google.android.material.R.string.clear_text_end_icon_content_description,\n                        drawableRes = R.drawable.baseline_close_24,\n                        onButtonClick = onClearClick\n                    )\n                }\n            },\n            scrollBehavior = topAppBarScrollBehavior\n        )\n        HorizontalDivider(color = MaterialTheme.colorScheme.outline)\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/leaderboard/LeaderBoard.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.leaderboard\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.pager.HorizontalPager\nimport androidx.compose.foundation.pager.rememberPagerState\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Tab\nimport androidx.compose.material3.TabRow\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.LoadState\nimport androidx.paging.compose.LazyPagingItems\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.rank.Item\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.ui.screen.compoents.withAppBarColor\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.viewmodel.RankViewModel\nimport kotlinx.coroutines.launch\n\n@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)\n@Composable\nfun LeaderBoardScreen(\n    rankViewModel: RankViewModel = hiltViewModel(),\n    onRankItemClick: (Item) -> Unit,\n) {\n\n    val day = rankViewModel.dayRank.collectAsLazyPagingItems()\n    val week = rankViewModel.weekRank.collectAsLazyPagingItems()\n    val month = rankViewModel.monthRank.collectAsLazyPagingItems()\n    val total = rankViewModel.totalRank.collectAsLazyPagingItems()\n    val leaderboardString = listOf(\n        stringResource(id = R.string.day_rank),\n        stringResource(id = R.string.week_rank),\n        stringResource(id = R.string.month_rank),\n        stringResource(id = R.string.all_rank)\n    )\n    val layoutDirection = LocalLayoutDirection.current\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val scope = rememberCoroutineScope()\n    val columns = GridCells.Fixed(3)\n    val pagerState = rememberPagerState(\n        initialPage = 0,\n        initialPageOffsetFraction = 0f,\n        pageCount = leaderboardString::size\n    )\n\n    Scaffold(\n        modifier = Modifier.fillMaxSize(),\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(id = R.string.comic_rank))\n                },\n                scrollBehavior = topAppBarScrollBehavior\n            )\n        }\n    ) {\n        Column(\n            Modifier\n                .nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n                .fillMaxSize()\n                .padding(top = it.calculateTopPadding())\n        ) {\n            TabRow(\n                selectedTabIndex = pagerState.currentPage,\n                modifier = Modifier.fillMaxWidth(),\n                containerColor = withAppBarColor(topAppBarState = topAppBarScrollBehavior.state)\n            ) {\n                leaderboardString.forEachIndexed { index, s ->\n                    Tab(\n                        selected = pagerState.currentPage == index,\n                        onClick = {\n                            scope.launch {\n                                pagerState.animateScrollToPage(index)\n                            }\n                        },\n                        text = {\n                            Text(text = s)\n                        }\n                    )\n                }\n            }\n\n            HorizontalPager(\n                state = pagerState,\n            ) { index ->\n                when (index) {\n                    0 -> {\n                        LeaderBoradPage(day, columns, it, layoutDirection, onRankItemClick)\n                    }\n\n                    1 -> {\n                        LeaderBoradPage(\n                            day = week,\n                            columns = columns,\n                            it = it,\n                            layoutDirection = layoutDirection,\n                            onRankItemClick = onRankItemClick\n                        )\n                    }\n\n                    2 -> {\n                        LeaderBoradPage(\n                            day = month,\n                            columns = columns,\n                            it = it,\n                            layoutDirection = layoutDirection,\n                            onRankItemClick = onRankItemClick\n                        )\n                    }\n\n                    3 -> {\n                        LeaderBoradPage(\n                            day = total,\n                            columns = columns,\n                            it = it,\n                            layoutDirection = layoutDirection,\n                            onRankItemClick = onRankItemClick\n                        )\n                    }\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun LeaderBoradPage(\n    day: LazyPagingItems<Item>,\n    columns: GridCells.Fixed,\n    it: PaddingValues,\n    layoutDirection: LayoutDirection,\n    onRankItemClick: (Item) -> Unit,\n) {\n    when (day.loadState.refresh) {\n        is LoadState.Loading -> {\n            LoadingScreen()\n        }\n\n        is LoadState.Error -> {\n            ErrorScreen(errorMessage = stringResource(id = R.string.error)) {\n                day.refresh()\n            }\n        }\n\n        else -> {\n            LazyVerticalGrid(\n                columns = columns,\n                verticalArrangement = Arrangement.spacedBy(16.dp),\n                horizontalArrangement = Arrangement.spacedBy(16.dp),\n                contentPadding = it.copy(\n                    layoutDirection = layoutDirection,\n                    bottom = it.calculateBottomPadding(),\n                    start = 16.dp,\n                    end = 16.dp,\n                    top = 16.dp\n                ),\n            ) {\n                items(day.itemCount) { itemIndex ->\n                    val item = day[itemIndex]\n                    if (item != null) {\n                        LeaderBoardItem(\n                            item = item,\n                            onItemClick = onRankItemClick\n                        )\n                    } else {\n                        LeaderBoardItemPlaceholder()\n                    }\n                }\n                pagingLoadingIndication(\n                    loadState = day.loadState.append\n                ) {\n                    day.retry()\n                }\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/leaderboard/LeaderboardComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.leaderboard\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.rank.Item\nimport com.shicheeng.copymanga.ui.screen.compoents.CommonCover\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun LeaderBoardItem(\n    item: Item,\n    onItemClick: (Item) -> Unit,\n) {\n    Card(\n        modifier = Modifier.width(IntrinsicSize.Min),\n        onClick = {\n            onItemClick.invoke(item)\n        }\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(bottom = 4.dp)\n                .wrapContentSize()\n        ) {\n            CommonCover(\n                url = item.comic.cover,\n                contentDescription = item.comic.name\n            )\n            Text(\n                text = item.comic.name,\n                style = MaterialTheme.typography.titleSmall,\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis\n            )\n            Text(\n                text = item.comic.authorThat(),\n                style = MaterialTheme.typography.bodySmall,\n                modifier = Modifier.alpha(0.78f),\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis\n\n            )\n        }\n    }\n}\n\n@Composable\nfun LeaderBoardItemPlaceholder() {\n    Card(\n        modifier = Modifier.width(IntrinsicSize.Min),\n    ) {\n        Column(\n            modifier = Modifier\n                .padding(bottom = 4.dp)\n                .wrapContentSize()\n        ) {\n            CommonCover(\n                url = \"\",\n                contentDescription = \"\"\n            )\n            Text(\n                text = stringResource(id = R.string.waiting),\n                style = MaterialTheme.typography.titleSmall,\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis\n            )\n            Text(\n                text = stringResource(id = R.string.waiting),\n                style = MaterialTheme.typography.titleSmall,\n                modifier = Modifier.alpha(0.78f),\n                maxLines = 1,\n                overflow = TextOverflow.Ellipsis\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/personal/PersonalHeaderView.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.personal\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.KeyboardArrowRight\nimport androidx.compose.material3.Badge\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.ListItem\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.core.net.toUri\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.login.LocalLoginDataModel\nimport com.shicheeng.copymanga.ui.theme.ElevationTokens\n\nprivate const val AVATAR_HOST_URL = \"https://hi77-overseas.mangafuna.xyz/\"\n\nfun hostFor(string: String): String {\n    return if (string.toUri().scheme == \"https\") {\n        string\n    } else {\n        buildString {\n            append(AVATAR_HOST_URL)\n            append(string)\n        }\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun PersonalHeaderView(\n    localLoginDataModel: LocalLoginDataModel?,\n    click: () -> Unit,\n) {\n    val backgroundV = MaterialTheme.colorScheme.surfaceColorAtElevation(ElevationTokens.Level1)\n    Column(\n        modifier = Modifier.fillMaxWidth()\n    ) {\n        Image(\n            painter = painterResource(id = R.drawable.undraw_personal_file_re),\n            contentDescription = null,\n            modifier = Modifier\n                .height(150.dp)\n                .fillMaxWidth()\n                .padding(horizontal = 16.dp)\n                .clip(MaterialTheme.shapes.large)\n                .drawWithContent {\n                    drawRect(color = backgroundV)\n                    drawContent()\n                },\n            contentScale = ContentScale.FillHeight\n        )\n        Spacer(modifier = Modifier.height(16.dp))\n        ListItem(\n            headlineContent = {\n                Row(\n                    horizontalArrangement = Arrangement.Start,\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Text(\n                        text = localLoginDataModel?.nikeName\n                            ?: stringResource(id = R.string.no_login)\n                    )\n                    if (localLoginDataModel?.isExpired == true) {\n                        Badge(\n                            containerColor = MaterialTheme.colorScheme.errorContainer,\n                            contentColor = MaterialTheme.colorScheme.onErrorContainer,\n                            modifier = Modifier.padding(start = 4.dp)\n                        ) {\n                            Text(\n                                text = stringResource(id = R.string.login_expired),\n                                modifier = Modifier.padding(4.dp)\n                            )\n                        }\n                    }\n                }\n            },\n            leadingContent = {\n                if (localLoginDataModel != null) {\n                    AsyncImage(\n                        model = hostFor(localLoginDataModel.avatarImageUrl),\n                        contentDescription = null,\n                        modifier = Modifier\n                            .size(72.dp)\n                            .clip(CircleShape),\n                        placeholder = ColorPainter(MaterialTheme.colorScheme.secondaryContainer)\n                    )\n                } else {\n                    AvatarPlaceholder()\n                }\n            },\n            supportingContent = if (localLoginDataModel != null) {\n                {\n                    Text(text = localLoginDataModel.userName)\n                }\n            } else null,\n            trailingContent = {\n                Icon(\n                    imageVector = Icons.Default.KeyboardArrowRight,\n                    contentDescription = stringResource(id = R.string.topic_detail_text)\n                )\n            },\n            modifier = Modifier.clickable { click() }\n        )\n    }\n}\n\n@Composable\nfun AvatarPlaceholder() {\n    Image(\n        painter = painterResource(id = R.drawable.undraw_drink_coffee),\n        contentDescription = null,\n        modifier = Modifier\n            .size(72.dp)\n            .clip(CircleShape)\n    )\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/personal/PersonalScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.personal\n\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.StringRes\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.ListItem\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.viewmodel.PersonalViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun PersonalScreen(\n    viewModel: PersonalViewModel = hiltViewModel(),\n    onHistoryClick: () -> Unit,\n    onLibraryClick: () -> Unit,\n    onDownloadClick: () -> Unit,\n    onSubscribedClick: () -> Unit,\n    onPersonalHeaderClick: (isHadLoginUser: Boolean) -> Unit,\n    onSettingClick: () -> Unit,\n) {\n\n    val user by viewModel.user.collectAsState()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(id = R.string.personal))\n                }\n            )\n        }\n    ) {\n        LazyColumn(\n            modifier = Modifier.fillMaxSize(),\n            contentPadding = it\n        ) {\n            item(\n                key = PersonalToken.HEADER,\n                contentType = PersonalToken.HEADER\n            ) {\n                PersonalHeaderView(localLoginDataModel = user) {\n                    onPersonalHeaderClick(user != null)\n                }\n            }\n            item(\n                key = PersonalToken.TOP_DIVIDER,\n                contentType = PersonalToken.TOP_DIVIDER\n            ) {\n                HorizontalDivider()\n            }\n            item(\n                key = PersonalToken.ITEM_HISTORY,\n                contentType = PersonalToken.ITEM_HISTORY\n            ) {\n                PersonalItem(\n                    id = R.string.history,\n                    iconId = R.drawable.baseline_history_24,\n                    onClick = onHistoryClick\n                )\n            }\n            item {\n                PersonalItem(\n                    id = R.string.subscribe,\n                    iconId = R.drawable.baseline_rss_feed_24,\n                    onClick = onSubscribedClick\n                )\n            }\n            item(\n                key = PersonalToken.ITEM_BOOK_SHELF,\n                contentType = PersonalToken.ITEM_BOOK_SHELF\n            ) {\n                PersonalItem(\n                    id = R.string.shelf_cloud,\n                    iconId = R.drawable.outline_library_books_24,\n                    onClick = onLibraryClick\n                )\n            }\n            item(\n                key = PersonalToken.ITEM_DOWNLOADED_MANGA,\n                contentType = PersonalToken.ITEM_DOWNLOADED_MANGA\n            ) {\n                PersonalItem(\n                    id = R.string.download_manga,\n                    iconId = R.drawable.outline_download_24,\n                    onClick = onDownloadClick\n                )\n            }\n            item(\n                key = PersonalToken.BOTTOM_DIVIDER,\n                contentType = PersonalToken.BOTTOM_DIVIDER\n            ) {\n                HorizontalDivider()\n            }\n            item(\n                key = PersonalToken.ITEM_SETTING,\n                contentType = PersonalToken.ITEM_SETTING\n            ) {\n                PersonalItem(\n                    id = R.string.setting,\n                    iconId = R.drawable.ic_setting_outline,\n                    onClick = onSettingClick\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun PersonalItem(\n    @StringRes id: Int,\n    @DrawableRes iconId: Int,\n    onClick: () -> Unit,\n) {\n    ListItem(\n        headlineContent = {\n            Text(text = stringResource(id = id))\n        },\n        leadingContent = {\n            Icon(\n                painter = painterResource(id = iconId),\n                contentDescription = null\n            )\n        },\n        modifier = Modifier.clickable { onClick() }\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/personal/PersonalToken.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.personal\n\nenum class PersonalToken {\n    HEADER,\n    ITEM_HISTORY,\n    BOTTOM_DIVIDER,\n    ITEM_BOOK_SHELF,\n    ITEM_SETTING,\n    TOP_DIVIDER,\n    ITEM_DOWNLOADED_MANGA;\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/personal/personaldetail/PersonalDetail.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.personal.personaldetail\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.logininfoshort.LoginInfoShortDataModel\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.viewmodel.PersonalDetailViewModel\nimport retrofit2.HttpException\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun PersonalDetail(\n    personalDetailViewModel: PersonalDetailViewModel = hiltViewModel(),\n    onReLogin: () -> Unit,\n    onBack: () -> Unit,\n) {\n\n    val data by personalDetailViewModel.data.collectAsState()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = { Text(text = stringResource(R.string.personal_info)) },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onBack\n                    )\n                }\n            )\n        }\n    ) { padding ->\n        when (data) {\n            is UIState.Success -> {\n                val primary = (data as UIState.Success<LoginInfoShortDataModel>).content\n                Column(\n                    Modifier.padding(padding)\n                ) {\n                    PersonalDetailTwoRowText(\n                        secondaryText = primary.results.info.nickname,\n                        primaryText = stringResource(R.string.nickname_text)\n                    )\n                    PersonalDetailTwoRowText(\n                        secondaryText = primary.results.info.username,\n                        primaryText = stringResource(id = R.string.user_name_text)\n                    )\n                    PersonalDetailTwoRowText(\n                        primaryText = stringResource(R.string.gender),\n                        secondaryText = primary.results.info.gender.display\n                    )\n                }\n            }\n\n            is UIState.Loading -> {\n                LoadingScreen()\n            }\n\n            is UIState.Error<*> -> {\n                val error = (data as UIState.Error<*>).errorMessage\n                ErrorScreen(\n                    errorMessage = error.message ?: \"\",\n                    needSecondaryText = (error is HttpException) && (error.code() == 401),\n                    secondaryText = stringResource(id = R.string.re_login),\n                    onTry = {\n                        personalDetailViewModel.retry()\n                    },\n                    onSecondaryClick = onReLogin\n                )\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/personal/personaldetail/PersonalDetailTwoRowText.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.personal.personaldetail\n\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.dp\n\n\n@Composable\nfun PersonalDetailTwoRowText(\n    primaryText: () -> String,\n    secondaryText: () -> String,\n) {\n    Row(\n        modifier = Modifier.fillMaxSize()\n    ) {\n        Text(\n            text = primaryText(),\n            style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold),\n            color = MaterialTheme.colorScheme.onSurface,\n            modifier = Modifier.weight(1f)\n        )\n        Text(\n            text = secondaryText(),\n            style = MaterialTheme.typography.bodyMedium,\n            modifier = Modifier.weight(1f),\n            color = MaterialTheme.colorScheme.onSurfaceVariant\n        )\n    }\n}\n\n@Composable\nfun PersonalDetailTwoRowText(\n    primaryText: String,\n    secondaryText: String,\n) {\n    Row(\n        modifier = Modifier\n            .padding(horizontal = 16.dp, vertical = 4.dp)\n    ) {\n        Text(\n            text = primaryText,\n            style = MaterialTheme.typography.bodyMedium.copy(fontWeight = FontWeight.Bold),\n            color = MaterialTheme.colorScheme.onSurface,\n            modifier = Modifier.weight(1f)\n        )\n        Text(\n            text = secondaryText,\n            style = MaterialTheme.typography.bodyMedium,\n            modifier = Modifier.weight(1f),\n            color = MaterialTheme.colorScheme.onSurfaceVariant\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/main/subscribe/SubscribedScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.main.subscribe\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.foundation.lazy.grid.items\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.work.OneTimeWorkRequestBuilder\nimport androidx.work.WorkManager\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.server.work.DetectMangaUpdateWork\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.list.CommonListItem\nimport com.shicheeng.copymanga.util.copyComposable\nimport com.shicheeng.copymanga.viewmodel.SubscribedViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun SubScribeScreen(\n    viewModel: SubscribedViewModel = hiltViewModel(),\n    navClick: () -> Unit,\n    onPathWord: (String) -> Unit,\n) {\n    val data by viewModel.data.collectAsState()\n    val context = LocalContext.current\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(id = R.string.subscribe))\n                },\n                actions = {\n                    PlainButton(\n                        id = R.string.refresh,\n                        drawableRes = R.drawable.ic_baseline_loop\n                    ) {\n                        val workManager = WorkManager.getInstance(context)\n                        val oneTimeWorkRequest = OneTimeWorkRequestBuilder<DetectMangaUpdateWork>()\n                            .build()\n                        workManager.enqueue(oneTimeWorkRequest)\n                    }\n                },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = navClick\n                    )\n                },\n                scrollBehavior = topAppBarScrollBehavior\n            )\n        }\n    ) { paddingValues ->\n        LazyVerticalGrid(\n            contentPadding = paddingValues.copyComposable(\n                start = 16.dp,\n                end = 16.dp,\n                top = paddingValues.calculateTopPadding() + 16.dp,\n                bottom = paddingValues.calculateBottomPadding() + 16.dp\n            ),\n            verticalArrangement = Arrangement.spacedBy(16.dp),\n            horizontalArrangement = Arrangement.spacedBy(16.dp),\n            columns = GridCells.Fixed(3),\n            modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n        ) {\n            items(data) { historyItem ->\n                CommonListItem(\n                    url = historyItem.url,\n                    title = historyItem.name,\n                    author = historyItem.authorList.joinToString { it.name }\n                ) {\n                    onPathWord(historyItem.pathWord)\n                }\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaChapterComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.combinedClickable\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.AlertDialog\nimport androidx.compose.material3.Button\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.compose.ui.window.DialogProperties\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.util.UIState\n\n/**\n * 这是章节的列表，当列状态为[UIState.Error]不会显示任何内容。\n */\nfun LazyListScope.chapterList(\n    inSelectMode: Boolean,\n    selectChapters: List<LocalChapter>,\n    chapterState: UIState<List<LocalChapter>>,\n    webLookedUUID: String?,\n    onLongClick: (LocalChapter) -> Unit,\n    onClick: (LocalChapter) -> Unit,\n) {\n    if (chapterState is UIState.Error<*> || chapterState == UIState.Loading) {\n        return\n    }\n    val successState = chapterState as UIState.Success\n    items(\n        items = successState.content,\n        key = { it.hashCode() },\n        contentType = { MangaDetailKey.LIST_CHAPTER }\n    ) { eachChapter ->\n        ChapterItem(\n            inSelectMode = inSelectMode,\n            isSelected = selectChapters.contains(eachChapter),\n            title = eachChapter.name,\n            time = eachChapter.datetime_created,\n            isDownload = eachChapter.isDownloaded,\n            onLongClick = {\n                onLongClick(eachChapter)\n            },\n            readIn = if (\n                eachChapter.isReadProgress\n                && !eachChapter.isReadFinish\n                && eachChapter.readIndex != (eachChapter.size - 1)\n            ) {\n                eachChapter.readIndex\n            } else null,\n            isRead = eachChapter.isReadFinish || eachChapter.readIndex == (eachChapter.size - 1),\n            isWebLooked = eachChapter.uuid == webLookedUUID\n        ) {\n            onClick(eachChapter)\n        }\n    }\n}\n\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\nfun ChapterItem(\n    inSelectMode: Boolean,\n    isSelected: Boolean,\n    isRead: Boolean,\n    title: String,\n    time: String,\n    readIn: Int? = null,\n    isDownload: Boolean = false,\n    isWebLooked: Boolean = false,\n    onLongClick: () -> Unit,\n    onClick: () -> Unit,\n) {\n    val textAlpha = remember(isRead) { if (isRead) .38f else 1f }\n    val textSubtitleAlpha = remember(isRead) { if (isRead) .38f else 0.78f }\n    Row(\n        verticalAlignment = Alignment.CenterVertically,\n        modifier = Modifier\n            .background(\n                if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.26f)\n                else Color.Transparent\n            )\n            .fillMaxWidth()\n            .combinedClickable(\n                onClick = {\n                    if (inSelectMode) {\n                        onLongClick()\n                    } else {\n                        onClick.invoke()\n                    }\n                },\n                onLongClick = {\n                    onLongClick.invoke()\n                }\n            )\n            .padding(start = 16.dp, top = 12.dp, end = 16.dp, bottom = 12.dp),\n    ) {\n        Row(\n            verticalAlignment = Alignment.CenterVertically\n        ) {\n            Column(\n                modifier = Modifier.weight(1f)\n            ) {\n                Text(\n                    text = title,\n                    maxLines = 1,\n                    overflow = TextOverflow.Ellipsis,\n                    style = MaterialTheme.typography.bodyMedium,\n                    modifier = Modifier.alpha(textAlpha)\n                )\n                Spacer(modifier = Modifier.height(6.dp))\n                Row(verticalAlignment = Alignment.CenterVertically) {\n                    Text(\n                        text = time,\n                        overflow = TextOverflow.Ellipsis,\n                        style = MaterialTheme.typography.bodyMedium.copy(fontSize = 12.sp),\n                        modifier = Modifier.alpha(textSubtitleAlpha)\n                    )\n                    when {\n                        readIn != null -> {\n                            Text(\n                                text = stringResource(\n                                    id = R.string.read_in,\n                                    formatArgs = arrayOf(readIn + 1)\n                                ),\n                                overflow = TextOverflow.Ellipsis,\n                                style = MaterialTheme.typography.labelSmall,\n                                color = MaterialTheme.colorScheme.onSurfaceVariant,\n                                modifier = Modifier\n                                    .alpha(textSubtitleAlpha)\n                                    .padding(start = 4.dp)\n                            )\n                        }\n\n                        isRead -> {\n                            Text(\n                                text = stringResource(R.string.read_finished),\n                                overflow = TextOverflow.Ellipsis,\n                                style = MaterialTheme.typography.labelSmall,\n                                modifier = Modifier\n                                    .alpha(textSubtitleAlpha)\n                                    .padding(start = 4.dp)\n                            )\n                        }\n                    }\n                }\n            }\n            if (isWebLooked) {\n                Icon(\n                    painter = painterResource(id = R.drawable.outline_cloud_24),\n                    contentDescription = stringResource(id = R.string.shelf_cloud),\n                    modifier = Modifier.padding(end = 4.dp)\n                )\n            }\n            if (isDownload) {\n                Icon(\n                    painter = painterResource(id = R.drawable.outline_download_for_offline_24),\n                    contentDescription = stringResource(id = R.string.download_manga)\n                )\n            }\n        }\n    }\n}\n\n@Composable\nfun TipDialog(\n    onDismiss: () -> Unit,\n    onPositive: () -> Unit,\n    onNegative: () -> Unit,\n) = AlertDialog(\n    onDismissRequest = onDismiss,\n    confirmButton = {\n        Button(\n            onClick = {\n                onPositive()\n                onDismiss()\n            }\n        ) {\n            Text(text = stringResource(R.string.enable))\n        }\n        onDismiss()\n    },\n    properties = DialogProperties(),\n    dismissButton = {\n        Button(\n            onClick = {\n                onNegative()\n                onDismiss()\n            }\n        ) {\n            Text(text = stringResource(R.string.not_enabled))\n        }\n    },\n    title = {\n        Text(text = stringResource(R.string.confrim_update))\n    },\n    text = {\n        Text(text = stringResource(R.string.enable_update_text))\n    }\n)"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaDetailBottomBar.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.theme.ElevationTokens\n\n@Composable\nfun MangaDetailBottomBar(\n    modifier: Modifier = Modifier,\n    bottomCornerSize: CornerSize = CornerSize(0.dp),\n    onDownloadClick: () -> Unit,\n    onMarkReadClick: () -> Unit,\n    onMarkNoReadClick: () -> Unit,\n) {\n    Surface(\n        shape = MaterialTheme.shapes.large.copy(\n            bottomStart = bottomCornerSize,\n            bottomEnd = bottomCornerSize\n        ),\n        tonalElevation = ElevationTokens.Level2,\n        modifier = modifier.fillMaxWidth()\n    ) {\n        Row(\n            horizontalArrangement = Arrangement.SpaceAround,\n            modifier = Modifier.padding(all = 16.dp)\n        ) {\n            PlainButton(\n                id = R.string.download_manga,\n                drawableRes = R.drawable.outline_download_24,\n                onButtonClick = onDownloadClick\n            )\n            PlainButton(\n                id = R.string.mark_to_read,\n                drawableRes = R.drawable.ic_done_all,\n                onButtonClick = onMarkReadClick\n            )\n            PlainButton(\n                id = R.string.mark_to_no_read,\n                drawableRes = R.drawable.baseline_remove_done_24,\n                onButtonClick = onMarkNoReadClick\n            )\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaDetailBottomSelector.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.ListItem\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ModalBottomSheet\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.info.Author\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun MangaDetailBottomSelector(\n    list: List<Author>,\n    onDismissRequest: () -> Unit,\n    onClick: (String) -> Unit,\n) = ModalBottomSheet(\n    onDismissRequest = onDismissRequest,\n    windowInsets = WindowInsets(\n        left = 0,\n        top = 0,\n        right = 0,\n        bottom = 0\n    )\n) {\n    Text(\n        text = stringResource(R.string.author_choice),\n        style = MaterialTheme.typography.titleLarge,\n        modifier = Modifier.padding(16.dp)\n    )\n    HorizontalDivider()\n    list.forEach { author ->\n        ListItem(\n            headlineContent = { Text(text = author.name) },\n            modifier = Modifier.clickable {\n                onClick(author.pathWord)\n                onDismissRequest()\n            },\n            leadingContent = {\n                Icon(\n                    painter = painterResource(id = R.drawable.baseline_person_24),\n                    contentDescription = null\n                )\n            },\n            supportingContent = {\n                Text(text = author.pathWord)\n            }\n        )\n    }\n    HorizontalDivider()\n    Text(\n        text = stringResource(R.string.author_combine, list.size),\n        style = MaterialTheme.typography.labelMedium,\n        color = MaterialTheme.colorScheme.onSurfaceVariant,\n        modifier = Modifier\n            .padding(16.dp)\n            .navigationBarsPadding()\n    )\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaDetailHeader.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.IntrinsicSize\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.ProvideTextStyle\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TextButton\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.blur\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.vector.ImageVector\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.res.vectorResource\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.ui.screen.compoents.MangaCover\nimport com.shicheeng.copymanga.util.click\n\n\n@Composable\nfun DetailInfoBox(\n    modifier: Modifier = Modifier,\n    mangaInfoDataModel: MangaHistoryDataModel,\n    topPadding: Dp,\n    onAuthorClicked: () -> Unit,\n) {\n    Box(modifier = modifier) {\n        val backDropColors = listOf(\n            Color.Transparent,\n            MaterialTheme.colorScheme.background\n        )\n        AsyncImage(\n            model = mangaInfoDataModel.url,\n            contentDescription = null,\n            contentScale = ContentScale.Crop,\n            modifier = Modifier\n                .matchParentSize()\n                .drawWithContent {\n                    drawContent()\n                    drawRect(\n                        brush = Brush.verticalGradient(backDropColors)\n                    )\n                }\n                .blur(4.dp)\n                .alpha(.2f)\n        )\n        DetailHeader(\n            mangaInfoDataModel = mangaInfoDataModel,\n            onAuthorClicked = onAuthorClicked,\n            topPadding = topPadding\n        )\n    }\n}\n\n@Composable\nfun DetailHeader(\n    mangaInfoDataModel: MangaHistoryDataModel,\n    topPadding: Dp,\n    onAuthorClicked: () -> Unit,\n) {\n    Row(\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(top = 16.dp + topPadding, start = 16.dp, end = 16.dp)\n    ) {\n        MangaCover.Small(\n            url = mangaInfoDataModel.url,\n            shape = MaterialTheme.shapes.medium\n        )\n        Column(\n            modifier = Modifier\n                .weight(1f)\n                .padding(start = 16.dp)\n        ) {\n            Text(\n                text = mangaInfoDataModel.name,\n                style = MaterialTheme.typography.titleLarge\n            )\n            Spacer(modifier = Modifier.height(2.dp))\n            Text(\n                text = mangaInfoDataModel.alias\n                    ?: stringResource(id = R.string.no_alias),\n                style = MaterialTheme.typography.titleSmall,\n                color = MaterialTheme.colorScheme.onSurfaceVariant\n            )\n            Text(\n                text = mangaInfoDataModel.authorList.joinToString { it.name },\n                style = MaterialTheme.typography.titleSmall.copy(fontWeight = FontWeight.Bold),\n                color = MaterialTheme.colorScheme.primary,\n                modifier = Modifier\n                    .padding(top = 4.dp)\n                    .click { onAuthorClicked() }\n            )\n            Row(verticalAlignment = Alignment.CenterVertically) {\n                Icon(\n                    painter = painterResource(\n                        id = when (mangaInfoDataModel.mangaStatusId) {\n                            0 -> {\n                                R.drawable.ic_baseline_loop\n                            }\n\n                            1 -> {\n                                R.drawable.ic_done_all\n                            }\n\n                            else -> {\n                                R.drawable.outline_do_not_disturb_24\n                            }\n                        }\n                    ),\n                    contentDescription = null,\n                    modifier = Modifier\n                        .padding(end = 4.dp)\n                        .size(16.dp),\n                    tint = MaterialTheme.colorScheme.onSurfaceVariant\n                )\n                ProvideTextStyle(value = MaterialTheme.typography.bodyMedium) {\n                    Text(\n                        text = mangaInfoDataModel.mangaStatus,\n                        color = MaterialTheme.colorScheme.onSurfaceVariant\n                    )\n                    DotText()\n                    Text(\n                        text = mangaInfoDataModel.mangaRegion,\n                        color = MaterialTheme.colorScheme.onSurfaceVariant\n                    )\n                }\n            }\n            Row(verticalAlignment = Alignment.CenterVertically) {\n                Icon(\n                    painter = painterResource(id = R.drawable.ic_baseline_hot),\n                    contentDescription = null,\n                    modifier = Modifier\n                        .padding(end = 4.dp)\n                        .size(16.dp)\n                )\n                Text(\n                    text = mangaInfoDataModel.mangaPopularNumber,\n                    style = MaterialTheme.typography.bodyMedium\n                )\n            }\n            Text(\n                text = stringResource(\n                    R.string.last_update,\n                    mangaInfoDataModel.mangaLastUpdate\n                ),\n                color = MaterialTheme.colorScheme.onSurface,\n                modifier = Modifier.padding(top = 4.dp),\n                style = MaterialTheme.typography.bodyMedium\n            )\n        }\n    }\n}\n\n\n@Composable\nfun DetailRowInfo(\n    isCollect: Boolean,\n    isSubscribed: Boolean,\n    onCollectClicked: () -> Unit,\n    onSubscribedClick: () -> Unit,\n    onCommentClick: () -> Unit,\n) {\n    /*从Tachiyomi直接复制来的，这个比较简单就不自己想办法写了*/\n    val defaultActionButtonColor = MaterialTheme.colorScheme.onSurface.copy(alpha = .38f)\n    Row(\n        modifier = Modifier\n            .fillMaxWidth()\n            .height(IntrinsicSize.Min)\n            .padding(horizontal = 16.dp, vertical = 8.dp),\n        horizontalArrangement = Arrangement.SpaceAround,\n        verticalAlignment = Alignment.CenterVertically\n    ) {\n        MangaActionButton(\n            title = stringResource(if (isCollect) R.string.remove_add_to_lib else R.string.add_to_lib),\n            icon = ImageVector.vectorResource(\n                id = if (isCollect) {\n                    R.drawable.baseline_library_add_check_24\n                } else {\n                    R.drawable.baseline_library_add_24\n                }\n            ),\n            color = if (isCollect) MaterialTheme.colorScheme.primary else defaultActionButtonColor,\n            onClick = onCollectClicked\n        )\n        MangaActionButton(\n            title = stringResource(\n                id = if (isSubscribed) {\n                    R.string.unsubscribe_for_updates\n                } else {\n                    R.string.subscribe_for_updates\n                }\n            ),\n            icon = ImageVector.vectorResource(\n                id = if (isSubscribed) {\n                    R.drawable.iconmonstr_rss_feed_baseline\n                } else {\n                    R.drawable.iconmonstr_rss_feed_outline\n                }\n            ),\n            color = if (isSubscribed) MaterialTheme.colorScheme.primary else defaultActionButtonColor,\n            onClick = onSubscribedClick\n        )\n        MangaActionButton(\n            title = stringResource(id = R.string.comment_text),\n            icon = ImageVector.vectorResource(R.drawable.outline_comment_24),\n            color = MaterialTheme.colorScheme.primary,\n            onClick = onCommentClick\n        )\n    }\n}\n\n@Composable\nprivate fun RowScope.MangaActionButton(\n    title: String,\n    icon: ImageVector,\n    color: Color,\n    onClick: () -> Unit,\n) {\n    TextButton(\n        onClick = onClick,\n        modifier = Modifier.weight(1f),\n    ) {\n        Column(horizontalAlignment = Alignment.CenterHorizontally) {\n            Icon(\n                imageVector = icon,\n                contentDescription = null,\n                tint = color,\n                modifier = Modifier.size(20.dp),\n            )\n            Spacer(Modifier.height(4.dp))\n            Text(\n                text = title,\n                color = color,\n                fontSize = 12.sp,\n                textAlign = TextAlign.Center,\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun DotText() {\n    Text(text = \" • \")\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaDetailKey.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nenum class MangaDetailKey {\n    HEADER,ROW_INFO,SUMMARY,LIST_DESC,LIST_CHAPTER,BOTTOM_DESC\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaDetailScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nimport androidx.activity.compose.BackHandler\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.DropdownMenu\nimport androidx.compose.material3.DropdownMenuItem\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.ExtendedFloatingActionButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.hapticfeedback.HapticFeedbackType\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.zIndex\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.LocalSettingPreference\nimport com.shicheeng.copymanga.MangaReaderActivity\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pullrefresh.SwipeRefresh\nimport com.shicheeng.copymanga.ui.screen.compoents.pullrefresh.rememberSwipeRefreshState\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.viewmodel.MangaInfoViewModel\nimport soup.compose.material.motion.MaterialFade\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun MangaDetailScreen(\n    pathWord: String?,\n    viewModel: MangaInfoViewModel = hiltViewModel(),\n    onTagsClick: (MangaSortBean) -> Unit,\n    onAuthorClick: (String) -> Unit,\n    onCommentClick: (comicUUID: String) -> Unit,\n    onNavigation: () -> Unit,\n) {\n    val content by viewModel.mangaInfo.collectAsState()\n    val chapters by viewModel.chapters.collectAsState()\n    val selectedChapters by viewModel.selectChapter.collectAsState()\n    val lastWatchChapter by viewModel.lastWatchChapter.collectAsState()\n    val lastWebWatchChapter by viewModel.lastWebLookedChapter.collectAsState()\n\n    if (content is UIState.Loading) {\n        LoadingScreen()\n        return\n    }\n\n    if (content is UIState.Error<*>) {\n        ErrorScreen(\n            errorMessage = (content as UIState.Error<*>).errorMessage.message\n                ?: stringResource(id = R.string.error)\n        ) {\n            viewModel.chapterLoadForce()\n        }\n        return\n    }\n\n    val contentSuccess = content as UIState.Success\n    val layoutDirection = LocalLayoutDirection.current\n    val context = LocalContext.current\n    val refreshState = rememberSwipeRefreshState(isRefreshing = chapters is UIState.Loading)\n    var expanded by remember { mutableStateOf(false) }\n    val inSelectedMode by remember { derivedStateOf { selectedChapters.isNotEmpty() } }\n    var tipDialogShow by remember { mutableStateOf(false) }\n    val setting = LocalSettingPreference.current\n    val haptic = LocalHapticFeedback.current\n    var bottomAuthorsSelector by remember { mutableStateOf(false) }\n    val lazyListState = rememberLazyListState()\n\n\n    Scaffold(\n        topBar = {\n            val firstVisibleItemIndex by remember { derivedStateOf { lazyListState.firstVisibleItemIndex } }\n            val firstVisibleItemScrollOffset by remember { derivedStateOf { lazyListState.firstVisibleItemScrollOffset } }\n            val animatedTitleAlpha by animateFloatAsState(\n                if (firstVisibleItemIndex > 0) 1f else 0f,\n                label = \"titleAlpha\",\n            )\n            val animatedBgAlpha by animateFloatAsState(\n                if (firstVisibleItemIndex > 0 || firstVisibleItemScrollOffset > 0) 1f else 0f,\n                label = \"bgAlpha\",\n            )\n            TopAppBar(\n                title = {\n                    Text(\n                        text = stringResource(id = R.string.manga_detail),\n                        modifier = Modifier.alpha(\n                            if (inSelectedMode) 1f else animatedTitleAlpha,\n                        ),\n                        maxLines = 1,\n                        overflow = TextOverflow.Ellipsis\n                    )\n                },\n                navigationIcon = {\n                    if (inSelectedMode) {\n                        PlainButton(\n                            id = R.string.exit_select_mode,\n                            drawableRes = R.drawable.baseline_close_24\n                        ) {\n                            viewModel.deselectedAllItem()\n                        }\n                    } else {\n                        PlainButton(\n                            id = R.string.back_to_up,\n                            drawableRes = R.drawable.ic_arrow_back,\n                            onButtonClick = onNavigation\n                        )\n                    }\n                },\n                actions = {\n                    if (!inSelectedMode) {\n                        Box(\n                            modifier = Modifier\n                                .wrapContentSize(Alignment.TopStart)\n                        ) {\n                            PlainButton(\n                                id = R.string.download_manga,\n                                drawableRes = R.drawable.outline_file_download_24\n                            ) {\n                                expanded = true\n                            }\n                            DropdownMenu(\n                                expanded = expanded,\n                                onDismissRequest = {\n                                    expanded = false\n                                },\n                                modifier = Modifier\n                                    .widthIn(min = 112.dp, max = 280.dp)\n                                    .zIndex(1f)\n                            ) {\n                                DropdownMenuItem(\n                                    text = { Text(text = stringResource(R.string.download_first_5)) },\n                                    onClick = {\n                                        val firstChapters = viewModel.selectFirst5() ?: emptyList()\n                                        viewModel.downloadManga(\n                                            firstChapters\n                                                .map { x -> x.uuid }\n                                                .toTypedArray()\n                                        )\n                                        expanded = false\n                                    }\n                                )\n                                DropdownMenuItem(\n                                    text = { Text(text = stringResource(R.string.download_last_5)) },\n                                    onClick = {\n                                        val lastChapters = viewModel.selectLast5() ?: emptyList()\n                                        pathWord?.let {\n                                            lastChapters\n                                                .map { x -> x.uuid }\n                                                .toTypedArray()\n\n                                        }\n                                        expanded = false\n                                    }\n                                )\n                                DropdownMenuItem(\n                                    text = { Text(text = stringResource(id = R.string.download_all)) },\n                                    onClick = {\n                                        if (chapters is UIState.Success) {\n                                            val uuids =\n                                                ((chapters as UIState.Success<List<LocalChapter>>).content)\n                                                    .map { x -> x.uuid }\n                                                    .toTypedArray()\n                                            viewModel.downloadManga(uuids)\n                                        }\n                                        expanded = false\n                                    }\n                                )\n                            }\n                        }\n                    }\n                },\n                colors = TopAppBarDefaults.topAppBarColors(\n                    containerColor = MaterialTheme.colorScheme\n                        .surfaceColorAtElevation(3.dp)\n                        .copy(alpha = if (inSelectedMode) 1f else animatedBgAlpha),\n                ),\n            )\n        },\n        modifier = Modifier.fillMaxSize(),\n        floatingActionButton = {\n            MaterialFade(\n                visible = chapters is UIState.Success && !inSelectedMode\n            ) {\n                ExtendedFloatingActionButton(\n                    onClick = {\n                        if (setting.webReadPoint) {\n                            //漫画UUID\n                            val uuid = lastWebWatchChapter?.results?.browse?.chapterUuid\n                                ?: lastWatchChapter?.uuid\n                                ?: (chapters as UIState.Success).content[0].uuid\n                            //漫画PathWord\n                            val pathWord2 = lastWebWatchChapter?.results?.browse?.pathWord\n                                ?: lastWatchChapter?.comicPathWord\n                                ?: pathWord\n                                ?: (chapters as UIState.Success).content[0].comicPathWord\n                            val intent = MangaReaderActivity.newInstance(\n                                context = context,\n                                pathWord = pathWord2,\n                                uuid = uuid\n                            )\n                            context.startActivity(intent)\n                        } else {\n                            (lastWatchChapter ?: (chapters as UIState.Success).content[0]).run {\n                                val intent = MangaReaderActivity.newInstance(\n                                    context = context,\n                                    pathWord = comicPathWord,\n                                    uuid = uuid\n                                )\n                                context.startActivity(intent)\n                            }\n                        }\n                    },\n                    text = {\n                        Text(\n                            text = if (lastWatchChapter != null && contentSuccess.content.positionChapter != 0) {\n                                stringResource(id = R.string.continue_read)\n                            } else {\n                                stringResource(id = R.string.start_read)\n                            }\n                        )\n                    },\n                    icon = {\n                        Icon(\n                            painter = painterResource(id = R.drawable.baseline_play_arrow_24),\n                            contentDescription = null\n                        )\n                    },\n                    expanded = true\n                )\n            }\n        },\n        bottomBar = {\n            AnimatedVisibility(\n                visible = inSelectedMode,\n                enter = expandVertically() + fadeIn(),\n                exit = shrinkVertically() + fadeOut()\n            ) {\n                MangaDetailBottomBar(\n                    onDownloadClick = {\n                        val downloadUUIDs = selectedChapters.map { it.uuid }.toTypedArray()\n                        viewModel.downloadManga(downloadUUIDs)\n                        viewModel.deselectedAllItem()\n                    },\n                    onMarkReadClick = {\n                        viewModel.comicMarkRead(isRead = true)\n                    }\n                ) {\n                    viewModel.comicMarkRead(isRead = false)\n                }\n            }\n        }\n    ) { paddingValues ->\n        SwipeRefresh(\n            state = refreshState,\n            onRefresh = {\n                viewModel.chapterLoadForce()\n            },\n            indicatorPadding = paddingValues\n        ) {\n            LazyColumn(\n                modifier = Modifier\n                    .fillMaxSize(),\n                contentPadding = paddingValues.copy(\n                    layoutDirection = layoutDirection,\n                    bottom = paddingValues.calculateBottomPadding() + 64.dp,\n                    top = 0.dp\n                ),\n                state = lazyListState\n            ) {\n                item(\n                    key = MangaDetailKey.HEADER,\n                    contentType = MangaDetailKey.HEADER\n                ) {\n                    DetailInfoBox(\n                        mangaInfoDataModel = contentSuccess.content,\n                        topPadding = paddingValues.calculateTopPadding()\n                    ) {\n                        bottomAuthorsSelector = true\n                    }\n                }\n                item(\n                    key = MangaDetailKey.ROW_INFO,\n                    contentType = MangaDetailKey.ROW_INFO\n                ) {\n                    DetailRowInfo(\n                        onCommentClick = {\n                            onCommentClick(contentSuccess.content.comicUUID)\n                        },\n                        isCollect = lastWebWatchChapter?.results?.collect != null,\n                        onCollectClicked = {\n                            viewModel.comicAddWebLib(\n                                mangaUUID = contentSuccess.content.comicUUID,\n                                add = lastWebWatchChapter?.results?.collect == null\n                            )\n                        },\n                        isSubscribed = contentSuccess.content.isSubscribe,\n                        onSubscribedClick = {\n                            tipDialogShow = true\n                            viewModel.comicUpdate(contentSuccess.content.isSubscribe.not())\n                        }\n                    )\n                }\n                item(\n                    key = MangaDetailKey.SUMMARY,\n                    contentType = MangaDetailKey.SUMMARY\n                ) {\n                    MangaExpandSummary(\n                        defaultExpandState = false,\n                        description = contentSuccess.content.mangaDetail,\n                        tags = {\n                            contentSuccess.content.themeList\n                        },\n                        onTagsClick = onTagsClick\n                    )\n                }\n                item(\n                    key = MangaDetailKey.LIST_DESC,\n                    contentType = MangaDetailKey.LIST_DESC\n                ) {\n                    Text(\n                        text = stringResource(R.string.chapters_list),\n                        modifier = Modifier.padding(all = 16.dp),\n                        style = MaterialTheme.typography.titleMedium\n                    )\n                }\n                chapterList(\n                    selectChapters = selectedChapters,\n                    inSelectMode = inSelectedMode,\n                    chapterState = chapters,\n                    onLongClick = {\n                        haptic.performHapticFeedback(HapticFeedbackType.LongPress)\n                        viewModel.selectItem(it, !selectedChapters.contains(it))\n                    },\n                    webLookedUUID = lastWebWatchChapter?.results?.browse?.chapterUuid\n                ) {\n                    val intent = MangaReaderActivity.newInstance(context, it.comicPathWord, it.uuid)\n                    context.startActivity(intent)\n                }\n                item(\n                    key = MangaDetailKey.BOTTOM_DESC,\n                    contentType = MangaDetailKey.BOTTOM_DESC\n                ) {\n                    Column(\n                        modifier = Modifier.padding(16.dp)\n                    ) {\n                        Icon(\n                            painter = painterResource(id = R.drawable.ic_manga_info_main),\n                            contentDescription = stringResource(R.string.disclaimer)\n                        )\n                        Spacer(modifier = Modifier.height(8.dp))\n                        Text(\n                            text = stringResource(R.string.general_tips),\n                            style = MaterialTheme.typography.labelMedium,\n                            color = MaterialTheme.colorScheme.onSurfaceVariant\n                        )\n                        Text(\n                            text = stringResource(R.string.general_warning),\n                            style = MaterialTheme.typography.labelMedium,\n                            color = MaterialTheme.colorScheme.onSurfaceVariant\n                        )\n                    }\n                }\n            }\n        }\n    }\n\n    if (tipDialogShow && !setting.hasKey(SettingPref.KEY_ENABLE_COMIC_UPDATE)) {\n        TipDialog(\n            onDismiss = {\n                tipDialogShow = false\n            },\n            onPositive = {\n                viewModel.enableComicUpdate(true)\n            }\n        ) {\n            viewModel.enableComicUpdate(false)\n        }\n    }\n\n    if (bottomAuthorsSelector) {\n        MangaDetailBottomSelector(\n            list = contentSuccess.content.authorList,\n            onDismissRequest = { bottomAuthorsSelector = false },\n            onClick = {\n                onAuthorClick(it)\n            }\n        )\n    }\n\n    BackHandler(enabled = inSelectedMode) {\n        viewModel.deselectedAllItem()\n    }\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaDetailSummary.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi\nimport androidx.compose.animation.graphics.res.animatedVectorResource\nimport androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter\nimport androidx.compose.animation.graphics.vector.AnimatedImageVector\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ExperimentalLayoutApi\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.text.selection.SelectionContainer\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.SuggestionChip\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.SubcomposeLayout\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.util.click\nimport kotlin.math.roundToInt\n\n\nprivate val whitespaceLineRegex = Regex(\"[\\\\r\\\\n]{2,}\", setOf(RegexOption.MULTILINE))\n\n@OptIn(ExperimentalLayoutApi::class)\n@Composable\nfun MangaExpandSummary(\n    modifier: Modifier = Modifier,\n    defaultExpandState: Boolean,\n    description: String?,\n    tags: () -> List<MangaSortBean>?,\n    onTagsClick: (MangaSortBean) -> Unit,\n) {\n\n    Column(modifier = modifier) {\n        val (expand, onExpand) = rememberSaveable {\n            mutableStateOf(defaultExpandState)\n        }\n        val desc = description.takeIf { !it.isNullOrBlank() }\n            ?: stringResource(id = R.string.no_description)\n        val trimmedDescription = remember(desc) {\n            desc.replace(whitespaceLineRegex, \"\\n\")\n                .trimEnd()\n        }\n        MangaSummary(\n            expandedDescription = desc,\n            shrunkDescription = trimmedDescription,\n            expanded = expand,\n            modifier = Modifier\n                .padding(top = 8.dp)\n                .padding(horizontal = 16.dp)\n                .click { onExpand(!expand) }\n        )\n        val tag = tags()\n        if (tag != null) {\n            FlowRow(\n                modifier = Modifier.padding(horizontal = 16.dp),\n                horizontalArrangement = Arrangement.spacedBy(4.dp)\n            ) {\n                tag.forEach {\n                    SuggestionChip(\n                        onClick = { onTagsClick(it) },\n                        label = {\n                            Text(text = it.pathName)\n                        }\n                    )\n                }\n            }\n        }\n    }\n\n}\n\n@OptIn(ExperimentalAnimationGraphicsApi::class)\n@Composable\nprivate fun MangaSummary(\n    expandedDescription: String,\n    shrunkDescription: String,\n    expanded: Boolean,\n    modifier: Modifier = Modifier,\n) {\n    var expandedHeight by remember { mutableIntStateOf(0) }\n    var shrunkHeight by remember { mutableIntStateOf(0) }\n    val heightDelta = remember(expandedHeight, shrunkHeight) { expandedHeight - shrunkHeight }\n    val animProgress by animateFloatAsState(if (expanded) 1f else 0f)\n    val scrimHeight = with(LocalDensity.current) { remember { 24.sp.roundToPx() } }\n\n    SubcomposeLayout(modifier = modifier.clipToBounds()) { constraints ->\n        val shrunkPlaceable = subcompose(\"description-s\") {\n            Text(\n                text = \"\\n\\n\", // Shows at least 3 lines\n                style = MaterialTheme.typography.bodyMedium,\n            )\n        }.map { it.measure(constraints) }\n        shrunkHeight = shrunkPlaceable.maxByOrNull { it.height }?.height ?: 0\n\n        val expandedPlaceable = subcompose(\"description-l\") {\n            Text(\n                text = expandedDescription,\n                style = MaterialTheme.typography.bodyMedium,\n            )\n        }.map { it.measure(constraints) }\n        expandedHeight =\n            expandedPlaceable.maxByOrNull { it.height }?.height?.coerceAtLeast(shrunkHeight) ?: 0\n\n        val actualPlaceable = subcompose(\"description\") {\n            SelectionContainer {\n                Text(\n                    text = if (expanded) expandedDescription else shrunkDescription,\n                    maxLines = Int.MAX_VALUE,\n                    style = MaterialTheme.typography.bodyMedium,\n                    color = MaterialTheme.colorScheme.onBackground,\n                    modifier = Modifier.alpha(.78f),\n                )\n            }\n        }.map { it.measure(constraints) }\n\n        val scrimPlaceable = subcompose(\"scrim\") {\n            val colors = listOf(Color.Transparent, MaterialTheme.colorScheme.background)\n            Box(\n                modifier = Modifier.background(Brush.verticalGradient(colors = colors)),\n                contentAlignment = Alignment.Center,\n            ) {\n                val image = AnimatedImageVector.animatedVectorResource(R.drawable.ic_arrow_avd)\n                Icon(\n                    painter = rememberAnimatedVectorPainter(image, !expanded),\n                    contentDescription = stringResource(if (expanded) R.string.manga_info_collapse else R.string.manga_info_expand),\n                    tint = MaterialTheme.colorScheme.onBackground,\n                    modifier = Modifier.background(Brush.radialGradient(colors = colors.asReversed())),\n                )\n            }\n        }.map { it.measure(Constraints.fixed(width = constraints.maxWidth, height = scrimHeight)) }\n\n        val currentHeight = shrunkHeight + ((heightDelta + scrimHeight) * animProgress).roundToInt()\n        layout(constraints.maxWidth, currentHeight) {\n            actualPlaceable.forEach {\n                it.place(0, 0)\n            }\n\n            val scrimY = currentHeight - scrimHeight\n            scrimPlaceable.forEach {\n                it.place(0, scrimY)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/manga/MangaDetailVerticalIcon.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.manga\n\nimport androidx.annotation.DrawableRes\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.unit.dp\nimport com.shicheeng.copymanga.util.click\n\n@Composable\nfun VerticalIcon(\n    modifier: Modifier = Modifier,\n    @DrawableRes iconId: () -> Int,\n    text: String,\n    click: () -> Unit,\n) {\n    Column(\n        modifier = modifier.click { click() },\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Icon(\n            painter = painterResource(id = iconId()),\n            contentDescription = text,\n            modifier = Modifier.padding(4.dp),\n            tint = MaterialTheme.colorScheme.onSurface\n        )\n        Text(\n            text = text,\n            color = MaterialTheme.colorScheme.onSurface,\n            modifier = Modifier.padding(horizontal = 4.dp),\n            style = MaterialTheme.typography.labelMedium\n        )\n    }\n}\n\n@Composable\nfun VerticalIcon(\n    modifier: Modifier = Modifier,\n    @DrawableRes iconId: () -> Int,\n    text: String,\n) {\n    Column(\n        modifier = modifier,\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Icon(\n            painter = painterResource(id = iconId()),\n            contentDescription = text,\n            modifier = Modifier.padding(4.dp),\n            tint = MaterialTheme.colorScheme.onSurface\n        )\n        Text(\n            text = text,\n            color = MaterialTheme.colorScheme.onSurface,\n            modifier = Modifier.padding(horizontal = 4.dp),\n            style = MaterialTheme.typography.labelMedium\n        )\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/search/SearchResultScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.search\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.search.SearchResultDataModel\nimport com.shicheeng.copymanga.ui.screen.compoents.EmptyDataScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.ui.screen.list.CommonListItem\nimport com.shicheeng.copymanga.util.copyComposable\nimport com.shicheeng.copymanga.viewmodel.SearchResultViewModel\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun SearchResultScreen(\n    searchWord: String?,\n    viewModel: SearchResultViewModel = hiltViewModel(),\n    onNavigation: () -> Unit,\n    onItemClick: (SearchResultDataModel) -> Unit,\n) {\n\n    val searchResultList = viewModel.searchResult.collectAsLazyPagingItems()\n\n    if (searchWord != null) {\n        LaunchedEffect(key1 = searchWord) {\n            viewModel.loadSearch(searchWord)\n        }\n    }\n\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Column(modifier = Modifier.fillMaxWidth()) {\n                        Text(\n                            text = stringResource(id = R.string.search_result),\n                            style = MaterialTheme.typography.titleLarge,\n                            color = MaterialTheme.colorScheme.onSurface\n                        )\n                        Text(\n                            text = searchWord\n                                ?: stringResource(id = android.R.string.unknownName),\n                            style = MaterialTheme.typography.titleSmall,\n                            color = MaterialTheme.colorScheme.onSurfaceVariant\n                        )\n                    }\n                },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onNavigation\n                    )\n                }\n            )\n        }\n    ) {\n        Box(\n            modifier = Modifier\n                .fillMaxSize(),\n        ) {\n            if (searchResultList.itemSnapshotList.isNotEmpty()) {\n                LazyVerticalGrid(\n                    columns = GridCells.Fixed(3),\n                    contentPadding = it.copyComposable(\n                        end = 16.dp,\n                        start = 16.dp,\n                    ),\n                    verticalArrangement = Arrangement.spacedBy(16.dp),\n                    horizontalArrangement = Arrangement.spacedBy(8.dp),\n                    modifier = Modifier.fillMaxSize()\n                ) {\n                    items(searchResultList.itemCount) { itemIndex ->\n                        searchResultList[itemIndex]?.let { item ->\n                            CommonListItem(\n                                url = item.cover,\n                                title = item.name,\n                                author = item.authorReformation()\n                            ) {\n                                onItemClick(item)\n                            }\n                        }\n                    }\n                    pagingLoadingIndication(\n                        loadState = searchResultList.loadState.append\n                    ) {\n                        searchResultList.retry()\n                    }\n                }\n            } else {\n                EmptyDataScreen(\n                    tipText = stringResource(id = R.string.search_is_empty)\n                )\n            }\n        }\n\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/Setting.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting\n\nimport android.app.Activity\nimport android.content.Context\nimport android.content.Intent\nimport android.net.Uri\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.expandVertically\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkVertically\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.res.stringResource\nimport androidx.core.content.ContextCompat\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport com.shicheeng.copymanga.LocalSettingPreference\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.fm.domain.makeDirIfNoExist\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\nimport com.shicheeng.copymanga.server.work.DetectMangaUpdateWork\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.VerticalFastScroller\nimport com.shicheeng.copymanga.util.FileCacheUtils\nimport com.shicheeng.copymanga.util.ThemeMode\nimport com.shicheeng.copymanga.util.copy\nimport com.shicheeng.copymanga.util.setSystemNightMode\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport java.io.File\n\n@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)\n@Composable\nfun SettingScreen(\n    viewModel: SettingViewModel = hiltViewModel(),\n    onNavigateClick: () -> Unit,\n    onDownloadClick: () -> Unit,\n    onWorkerClick: () -> Unit,\n    onUserClick: () -> Unit,\n    onAboutClick: () -> Unit,\n) {\n\n    val settingPref = LocalSettingPreference.current\n    val layoutDirection = LocalLayoutDirection.current\n    val context = LocalContext.current\n    val resource = context.resources\n    val exCacheDir = context.cacheDir\n    val cache = getFileCacheDir(context)\n    val coroutine = rememberCoroutineScope()\n    var cacheDirSummary by remember { mutableStateOf(cache.getSize()) }\n    var cachePageSize by remember { mutableStateOf(exCacheDir.getSize()) }\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val readerMode by viewModel.readerMode.collectAsState()\n    val isUseForeignReq by viewModel.useForeignRequest.collectAsState()\n    val apiSelect by viewModel.apiSelected.collectAsState()\n    val turnOn by viewModel.isTurn.collectAsState()\n    val lazyListState = rememberLazyListState()\n\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = { Text(text = stringResource(id = R.string.setting)) },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back\n                    ) {\n                        onNavigateClick()\n                    }\n                },\n                scrollBehavior = topAppBarScrollBehavior\n            )\n        }\n    ) { padding ->\n        VerticalFastScroller(\n            listState = lazyListState,\n            topContentPadding = padding.calculateTopPadding()\n        ) {\n            LazyColumn(\n                contentPadding = padding.copy(\n                    layoutDirection = layoutDirection,\n                    bottom = padding.calculateBottomPadding()\n                ),\n                state = lazyListState,\n                modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n            ) {\n                groupText(R.string.login_text)\n                item {\n                    val model by viewModel.name.collectAsState()\n                    Preference(\n                        title = stringResource(id = R.string.login_personal),\n                        summary = model?.nikeName ?: stringResource(R.string.no_login),\n                        leaderIconRes = R.drawable.ic_person_center\n                    ) {\n                        onUserClick()\n                    }\n                }\n                item {\n                    val webPoint by viewModel.webPoint.collectAsState()\n                    SwitchPreference(\n                        title = stringResource(R.string.web_point_enable),\n                        summary = stringResource(R.string.web_point_enable_summary),\n                        selectValue = webPoint,\n                        leaderIconRes = R.drawable.baseline_webhook_24,\n                        onClick = {\n                            settingPref.enableWebReadPoint(it)\n                        }\n                    )\n                }\n                item {\n                    WarningPreference(supportText = stringResource(R.string.web_point_warning))\n                }\n                item {\n                    TipPreference(supportText = stringResource(R.string.web_point_tip))\n                }\n                groupText(R.string.pref_main)\n                item {\n                    val array1 =\n                        rememberSaveable { resource.getStringArray(R.array.orientation_array) }\n                    ListPreference(\n                        title = stringResource(id = R.string.reader_mode_tip),\n                        summary = array1[settingPref.readerModeEntity.indexOf(readerMode)],\n                        dialogSupportedText = stringResource(id = R.string.swith_reader_mode_dialog_summary),\n                        array = array1,\n                        selectValue = array1[settingPref.readerModeEntity.indexOf(readerMode)],\n                        arrayValue = settingPref.readerModeEntity,\n                        leaderIconRes = R.drawable.outline_chrome_reader_mode_24\n                    ) { index, array ->\n                        viewModel.setReaderMode(ReaderMode.valueOf(array[index]))\n                    }\n                }\n                item {\n                    SwitchPreference(\n                        title = stringResource(id = R.string.use_forgin_region),\n                        summary = stringResource(id = R.string.use_forgin_region_summary),\n                        selectValue = isUseForeignReq,\n                        leaderIconRes = R.drawable.outline_switch_access_shortcut_24\n                    ) {\n                        viewModel.isUseForeignRequest(isUse = it)\n                    }\n                }\n                item {\n                    TipPreference(supportText = stringResource(id = R.string.use_forgin_region_tip))\n                }\n                item {\n                    ListPreference(\n                        title = stringResource(id = R.string.select_api_header),\n                        summary = apiSelect,\n                        dialogSupportedText = stringResource(id = R.string.switch_api_dialog_summary),\n                        array = resource.getStringArray(R.array.api_header),\n                        selectValue = apiSelect,\n                        arrayValue = resource.getStringArray(R.array.api_header_value),\n                        leaderIconRes = R.drawable.outline_cell_wifi_24,\n                    ) { index, array ->\n                        viewModel.selectApi(array[index])\n                    }\n                }\n                item {\n                    SwitchPreference(\n                        title = stringResource(id = R.string.subscribe_for_updates),\n                        summary = stringResource(id = R.string.subscribe_for_updates_summary),\n                        selectValue = turnOn,\n                        leaderIconRes = R.drawable.baseline_rss_feed_24\n                    ) {\n                        settingPref.enableComicsUpdateFetch(it)\n                        DetectMangaUpdateWork.readyToStart(\n                            isEnable = it,\n                            context = context,\n                            settingPref = settingPref\n                        )\n                    }\n                }\n                item {\n                    TipPreference(supportText = stringResource(R.string.tip_subscribe))\n                }\n                item(key = \"KEY_EDIT_TEXT_FOR_UPDATE_DETECT\") {\n                    AnimatedVisibility(\n                        visible = turnOn,\n                        enter = expandVertically() + fadeIn(),\n                        exit = shrinkVertically() + fadeOut(),\n                    ) {\n                        val time by viewModel.timeInterval.collectAsState()\n                        EditTextPreference(\n                            title = stringResource(id = R.string.time_detect),\n                            summary = time.toString(),\n                            dialogSupportedText = stringResource(id = R.string.time_detect_summary),\n                            originalValue = time.toString(),\n                            leaderIconRes = R.drawable.outline_timer_24,\n                            modifier = Modifier.animateItemPlacement(),\n                            onInput = {\n                                settingPref.editTimeInterval(it.toInt())\n                                DetectMangaUpdateWork.readyToStart(\n                                    isEnable = settingPref.enableComicsUpdate.value,\n                                    context = context,\n                                    settingPref = settingPref,\n                                    takeInterval = it.toInt()\n                                )\n                            }\n                        )\n                    }\n                }\n                item {\n                    val dataMap = mapOf(\n                        IN_WIFI to stringResource(id = R.string.only_wifi),\n                        IN_CHARGING to stringResource(id = R.string.only_charging),\n                        IN_BATTERY_NOT_LOW to stringResource(id = R.string.low_power)\n                    )\n                    val selected by viewModel.updateConstants.collectAsState()\n                    MutableSelectListPreference(\n                        title = stringResource(id = R.string.update_constant),\n                        dialogSupportedText = stringResource(id = R.string.update_constant_support_text),\n                        mapValue = dataMap,\n                        selectValue = selected,\n                        leaderIconRes = R.drawable.outline_auto_mode_24,\n                        summaryProvider = { valueMap ->\n                            valueMap.filter {\n                                selected.contains(it.key)\n                            }.values.takeIf { it.isNotEmpty() }\n                                ?.joinToString()\n                                ?: stringResource(id = R.string.no_select_constants)\n                        },\n                        onOK = {\n                            settingPref.changeUpdateConstant(it)\n                            ContextCompat.getMainExecutor(context).execute {\n                                DetectMangaUpdateWork.readyToStart(\n                                    isEnable = settingPref.enableComicsUpdate.value,\n                                    context = context,\n                                    settingPref = settingPref\n                                )\n                            }\n                        }\n                    )\n                }\n                groupText(R.string.system)\n                item {\n                    val themeName by viewModel.themeModeName.collectAsState()\n                    val array2 = arrayOf(\n                        stringResource(id = R.string.theme_with_system),\n                        stringResource(id = R.string.theme_light),\n                        stringResource(id = R.string.theme_dark),\n                    )\n                    ListPreference(\n                        title = stringResource(id = R.string.theme_mode),\n                        summary = when (ThemeMode.valueOf(themeName)) {\n                            ThemeMode.SYSTEM -> stringResource(id = R.string.theme_with_system)\n                            ThemeMode.DARK -> stringResource(id = R.string.theme_dark)\n                            ThemeMode.LIGHT -> stringResource(id = R.string.theme_light)\n                        },\n                        dialogSupportedText = stringResource(id = R.string.theme_mode_support_text),\n                        array = array2,\n                        selectValue = array2[settingPref.themeModeEntity.indexOf(themeName)],\n                        arrayValue = settingPref.themeModeEntity,\n                        leaderIconRes = R.drawable.outline_contrast_24,\n                        onItemClick = { i: Int, strings: Array<String> ->\n                            viewModel.setThemeMode(strings[i])\n                            setSystemNightMode(ThemeMode.valueOf(strings[i]))\n                            (context as Activity).recreate()\n                        }\n                    )\n                }\n                item {\n                    val isUse by settingPref.hyperTouch.collectAsState()\n                    SwitchPreference(\n                        title = stringResource(id = R.string.quick_touch),\n                        summary = stringResource(id = R.string.quick_touch_summary),\n                        selectValue = isUse,\n                        leaderIconRes = R.drawable.outline_touch_app_24,\n                        onClick = settingPref::isUseHyperTouch\n                    )\n                }\n                item {\n                    val enable by viewModel.cutoutDisplay.collectAsState()\n                    SwitchPreference(\n                        title = stringResource(id = R.string.cut_out_display),\n                        summary = stringResource(id = R.string.cut_out_display_summary),\n                        selectValue = enable,\n                        leaderIconRes = R.drawable.baseline_content_cut_24,\n                        onClick = viewModel::switchCutoutDisplay\n                    )\n                }\n                item {\n                    val isPause by settingPref.pauseUpdateDetector.collectAsState()\n                    SwitchPreference(\n                        title = stringResource(id = R.string.disable_update_detect),\n                        summary = stringResource(id = R.string.disable_update_summary),\n                        selectValue = isPause,\n                        leaderIconRes = R.drawable.outline_update_disabled_24,\n                        onClick = settingPref::isPauseDetectUpdate\n                    )\n                }\n                item {\n                    val cacheSize by viewModel.cacheSize.collectAsState()\n                    EditTextPreference(\n                        title = stringResource(R.string.cache_size_setting),\n                        summary = \"$cacheSize MB\",\n                        dialogSupportedText = stringResource(R.string.cache_size_setting_supporting_text),\n                        originalValue = cacheSize,\n                        leaderIconRes = R.drawable.baseline_cached_24,\n                        onInput = {\n                            viewModel.setCacheSize(it)\n                        }\n                    )\n                }\n                item {\n                    Preference(\n                        title = stringResource(id = R.string.clear_cache),\n                        summary = cacheDirSummary,\n                        leaderIconRes = R.drawable.outline_clean_hands_24\n                    ) {\n                        coroutine.launch {\n                            clearCache(cache) {\n                                cacheDirSummary = it\n                            }\n                        }\n                    }\n                }\n                item {\n                    Preference(\n                        title = stringResource(id = R.string.clear_pager_cache),\n                        summary = cachePageSize,\n                        leaderIconRes = R.drawable.outline_cleaning_services_24\n                    ) {\n                        coroutine.launch {\n                            clearCache(exCacheDir) {\n                                cachePageSize = it\n                            }\n                        }\n                    }\n                }\n                item {\n                    Preference(\n                        title = stringResource(R.string.work_information),\n                        summary = stringResource(R.string.work_info_summary),\n                        leaderIconRes = R.drawable.outline_work_history_24,\n                        onClick = onWorkerClick\n                    )\n                }\n                groupText(R.string.download_manga)\n                item {\n                    val onlyOnWifi by viewModel.onlyInWifi.collectAsState()\n                    SwitchPreference(\n                        title = stringResource(R.string.only_on_wifi),\n                        summary = stringResource(R.string.only_on_wifi_summary),\n                        selectValue = onlyOnWifi,\n                        leaderIconRes = R.drawable.outline_wifi_lock_24,\n                        onClick = {\n                            viewModel.changeDownloadConstants(it)\n                        }\n                    )\n                }\n                item {\n                    Preference(\n                        title = stringResource(R.string.download_list),\n                        summary = stringResource(id = R.string.see_the_download),\n                        leaderIconRes = R.drawable.outline_file_download_24,\n                        onClick = onDownloadClick\n                    )\n                }\n                groupText(R.string.perf_about)\n                item {\n                    Preference(\n                        title = stringResource(id = R.string.pref_app),\n                        summary = stringResource(id = R.string.pref_app_summary),\n                        leaderIconRes = R.drawable.iconmonstr_github_5\n                    ) {\n                        val intent = Intent(\n                            Intent.ACTION_VIEW,\n                            Uri.parse(\"https://github.com/shizheng233/CopyMangaJava\")\n                        )\n                        context.startActivity(intent)\n                    }\n                }\n                item {\n                    Preference(\n                        title = stringResource(id = R.string.about),\n                        summary = stringResource(id = R.string.pref_about_summary),\n                        leaderIconRes = R.drawable.ic_manga_info_main,\n                        onClick = onAboutClick,\n                    )\n                }\n            }\n        }\n    }\n\n}\n\nprivate fun getFileCacheDir(context: Context): File {\n    return (context.externalCacheDirs + context.cacheDir).firstNotNullOfOrNull {\n        it.makeDirIfNoExist()\n    }.let { file ->\n        checkNotNull(file) {\n            val dirs =\n                (context.externalCacheDirs + context.cacheDir).joinToString(\";\") {\n                    it.absolutePath\n                }\n            \"Cannot find directory for PagesCache: [$dirs]\"\n        }\n    }\n}\n\nprivate suspend inline fun clearCache(\n    file: File,\n    crossinline onFinished: (String) -> Unit,\n) = withContext(Dispatchers.IO) {\n    try {\n        file.deleteRecursively()\n        val size = file.getSize()\n        onFinished(size)\n    } catch (e: Exception) {\n        e.printStackTrace()\n    }\n}\n\nprivate fun File.getSize(): String {\n    return FileCacheUtils.getFormatSize(FileCacheUtils.getFolderSize(this).toDouble())\n}\n\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/SettingComponents.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting\n\nimport androidx.annotation.DrawableRes\nimport androidx.annotation.StringRes\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyListScope\nimport androidx.compose.foundation.selection.toggleable\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.ListItem\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Switch\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.hapticfeedback.HapticFeedbackType\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.unit.dp\nimport androidx.core.view.HapticFeedbackConstantsCompat\nimport com.shicheeng.copymanga.R\n\n/**\n * 使用compose写的设置界面。基本构件，表示在首选项层次结构中向用户显示的单个设置。处理最简单的点击事件。\n *\n * @param title 使用 String 设置此首选项的标题。\n * @param summary 使用 String 设置此首选项的摘要。\n * @param leaderIconRes 使用 DrawableResID 设置此首选项的图标。\n * @param onClick 设置单击此首选项时要调用的回调。\n */\n@Composable\nfun Preference(\n    modifier: Modifier = Modifier,\n    title: String,\n    summary: String,\n    @DrawableRes leaderIconRes: Int?,\n    onClick: () -> Unit,\n) {\n    ListItem(\n        headlineContent = {\n            Text(text = title)\n        },\n        supportingContent = {\n            Text(text = summary)\n        },\n        leadingContent = {\n            if (leaderIconRes != null) {\n                Icon(\n                    painter = painterResource(id = leaderIconRes),\n                    contentDescription = null,\n                    modifier = Modifier\n                        .padding(preferenceSpace)\n                        .size(24.dp),\n                )\n            } else {\n                Spacer(modifier = Modifier.size(preferenceSpaceSize))\n            }\n        },\n        modifier = modifier\n            .clickable { onClick() },\n    )\n}\n\n/**\n * 使用compose写的将条目列表显示为对话框的首选项。该首选项保存一个字符串值，该控件在点击时回弹出一个对话框来让用户选择与[array]对应的[arrayValue]，二者下标对应。\n *\n * @param dialogSupportedText 必传参数，用于显示对话框的介绍\n * @param title 必传参数，使用 String 设置此首选项的标题\n * @param summary 必传参数，使用 String 设置此首选项的摘要\n * @param array 必传参数，对话框的列表显示\n * @param selectValue 必传参数，对话框的被选择值\n * @param arrayValue 必传参数，与[array]下标对应的值\n * @param leaderIconRes 必传参数，使用 DrawableResID 设置此首选项的图标\n * @param onItemClick 点击列表的回调事件\n */\n@Composable\nfun ListPreference(\n    title: String,\n    summary: String,\n    dialogSupportedText: String,\n    array: Array<String>,\n    selectValue: String,\n    arrayValue: Array<String>,\n    @DrawableRes leaderIconRes: Int,\n    onItemClick: (Int, Array<String>) -> Unit,\n) {\n    var isShow by remember { mutableStateOf(false) }\n    Preference(title = title, summary = summary, leaderIconRes = leaderIconRes) {\n        isShow = true\n    }\n    if (isShow) {\n        SelectionDialog(\n            title = title,\n            summaryText = dialogSupportedText,\n            array = array,\n            selectValue = selectValue,\n            iconRes = leaderIconRes,\n            onItemClick = {\n                onItemClick(it, arrayValue)\n                isShow = false\n            },\n            onCancel = {\n                isShow = false\n            }\n        ) {\n            isShow = false\n        }\n    }\n}\n\n/**\n * 使用compose写的将条目列表显示为对话框的首选项。该首选项保存一个字符串值，该控件在点击时回弹出一个对话框来让用户选择[mapValue]里面的值。\n *\n * @param dialogSupportedText 必传参数，用于显示对话框的介绍\n * @param title 必传参数，使用 String 设置此首选项的标题\n * @param summaryProvider 必传参数，使用 String 设置此首选项的摘要\n * @param mapValue 必传参数，对话框的列表显示，选择的为[Map.keys]，显示的为[Map.values]\n * @param selectValue 必传参数，对话框的被选择值\n * @param leaderIconRes 必传参数，使用 DrawableResID 设置此首选项的图标\n * @param onOK 点击列表下面的按钮的回调事件\n */\n@Composable\nfun MutableSelectListPreference(\n    title: String,\n    dialogSupportedText: String,\n    mapValue: Map<String, String>,\n    summaryProvider: @Composable (Map<String, String>) -> String,\n    selectValue: Set<String>,\n    @DrawableRes leaderIconRes: Int,\n    onOK: (Set<String>) -> Unit,\n) {\n    var isShow by remember { mutableStateOf(false) }\n\n    Preference(\n        title = title,\n        summary = summaryProvider(mapValue),\n        leaderIconRes = leaderIconRes\n    ) {\n        isShow = true\n    }\n    if (isShow) {\n        MutableSelectedDialog(\n            title = title,\n            summaryText = dialogSupportedText,\n            mapValue = mapValue,\n            selectValues = selectValue,\n            iconRes = leaderIconRes,\n            onCancel = {\n                isShow = false\n            },\n            onOk = {\n                onOK(it)\n                isShow = false\n            }\n        ) {\n            isShow = false\n        }\n    }\n}\n\n/**\n * 使用compose写的开关设置组件，提供双状态可切换选项的首选项。\n *\n * @param title 使用 String 设置此首选项的标题。\n * @param summary 使用 String 设置此首选项的摘要。\n * @param leaderIconRes 使用 DrawableResID 设置此首选项的图标。\n * @param onClick 设置单击此首选项时要调用的回调。\n * @param selectValue 开关的选择\n */\n@Composable\nfun SwitchPreference(\n    title: String,\n    summary: String,\n    selectValue: Boolean,\n    @DrawableRes leaderIconRes: Int?,\n    onClick: (Boolean) -> Unit,\n) {\n    val mutableInteractionSource = remember {\n        MutableInteractionSource()\n    }\n    val hapticFeedbackConstants = LocalHapticFeedback.current\n    ListItem(\n        headlineContent = {\n            Text(text = title)\n        },\n        supportingContent = {\n            Text(text = summary)\n        },\n        trailingContent = {\n            Switch(\n                checked = selectValue,\n                onCheckedChange = onClick,\n                interactionSource = mutableInteractionSource,\n            )\n        },\n        leadingContent = {\n            if (leaderIconRes != null) {\n                Icon(\n                    painter = painterResource(id = leaderIconRes),\n                    contentDescription = null,\n                    modifier = Modifier\n                        .padding(preferenceSpace)\n                        .size(24.dp),\n                )\n            } else {\n                Spacer(modifier = Modifier.size(preferenceSpaceSize))\n            }\n        },\n        modifier = Modifier.toggleable(\n            value = selectValue,\n            interactionSource = mutableInteractionSource,\n            indication = LocalIndication.current,\n            role = Role.Switch\n        ) {\n            onClick(it)\n            hapticFeedbackConstants.performHapticFeedback(\n                hapticFeedbackType = HapticFeedbackType(\n                    value = if (it) {\n                        HapticFeedbackConstantsCompat.TOGGLE_ON\n                    } else {\n                        HapticFeedbackConstantsCompat.TOGGLE_OFF\n                    }\n                )\n            )\n\n        }\n    )\n}\n\n/**\n * 使用compose写的提示首选项，处理类似于[SwitchPreference]或者[Preference]这种有着需要被注意的细节问题。\n *\n * **注意**：不能用来写类似简介的文字，这个应该**只用来**提示用户。\n *\n * @param supportText 必传参数，显示的文字。\n */\n@Composable\nfun TipPreference(\n    supportText: String,\n) {\n    ListItem(\n        headlineContent = {\n            Row(\n                Modifier.padding(start = 16.dp + 48.dp),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                Icon(\n                    painter = painterResource(id = R.drawable.ic_manga_info_main),\n                    contentDescription = null\n                )\n                Text(\n                    text = supportText,\n                    style = MaterialTheme.typography.bodyMedium,\n                    modifier = Modifier.padding(start = 8.dp),\n                    color = MaterialTheme.colorScheme.onSurfaceVariant\n                )\n            }\n        }\n    )\n}\n\n/**\n * 使用compose写的警告首选项，处理类似于[SwitchPreference]或者[Preference]这种有着需要被注意的问题。\n *\n * **注意**：不能用来写类似简介的文字，这个应该**只用来**警告用户。\n *\n * @param supportText 必传参数，显示的文字。\n */\n@Composable\nfun WarningPreference(\n    supportText: String,\n) {\n    ListItem(\n        headlineContent = {\n            Row(\n                Modifier.padding(start = 16.dp + 48.dp),\n                verticalAlignment = Alignment.CenterVertically\n            ) {\n                Icon(\n                    painter = painterResource(id = R.drawable.baseline_warning_amber_24),\n                    contentDescription = null\n                )\n                Text(\n                    text = supportText,\n                    style = MaterialTheme.typography.bodyMedium,\n                    modifier = Modifier.padding(start = 8.dp),\n                )\n            }\n        }\n    )\n}\n\n/**\n * 使用compose写的将输入框显示为对话框的首选项。该首选项保存一个字符串值，该控件在点击时回弹出一个对话框来让用户选择输入文字。\n *\n * @param dialogSupportedText 必传参数，用于显示对话框的介绍\n * @param title 必传参数，使用 String 设置此首选项的标题\n * @param summary 必传参数，使用 String 设置此首选项的摘要\n * @param originalValue 必传参数，原始数据\n * @param leaderIconRes 必传参数，使用 DrawableResID 设置此首选项的图标。\n * @param onInput 必传参数，输入确认的回调\n */\n@Composable\nfun EditTextPreference(\n    modifier: Modifier = Modifier,\n    title: String,\n    summary: String,\n    dialogSupportedText: String,\n    originalValue: String,\n    @DrawableRes leaderIconRes: Int,\n    onInput: (String) -> Unit,\n) {\n    var isShow by remember { mutableStateOf(false) }\n    Preference(\n        modifier = modifier,\n        title = title,\n        summary = summary,\n        leaderIconRes = leaderIconRes\n    ) {\n        isShow = true\n    }\n    if (isShow) {\n        EditTextDialog(\n            title = title,\n            summaryText = dialogSupportedText,\n            originalValue = originalValue,\n            onDone = {\n                onInput(it)\n                isShow = false\n            }\n        ) {\n            isShow = false\n        }\n    }\n}\n\nfun LazyListScope.groupText(\n    @StringRes text: Int,\n) {\n    item(\n        key = text\n    ) {\n        Text(\n            text = stringResource(id = text),\n            Modifier\n                .padding(16.dp)\n                .padding(start = 48.dp + 16.dp),\n            style = MaterialTheme.typography.titleSmall,\n            color = MaterialTheme.colorScheme.primary\n        )\n    }\n}\n\nprivate val preferenceSpace = PaddingValues(all = 12.dp)\nprivate val preferenceSpaceSize = 48.dp"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/SettingDialog.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting\n\nimport androidx.annotation.DrawableRes\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.foundation.text.KeyboardActions\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.material3.Checkbox\nimport androidx.compose.material3.Divider\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedTextField\nimport androidx.compose.material3.RadioButton\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TextButton\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.toMutableStateList\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.window.Dialog\nimport com.shicheeng.copymanga.R\n\n@Composable\nfun SelectionDialog(\n    title: String,\n    summaryText: String?,\n    @DrawableRes iconRes: Int = R.drawable.baseline_format_list_bulleted_24,\n    array: Array<String>,\n    selectValue: String,\n    onItemClick: (Int) -> Unit,\n    onCancel: () -> Unit,\n    onDismissListener: () -> Unit,\n) = Dialog(\n    onDismissRequest = onDismissListener\n) {\n    Surface(\n        shape = RoundedCornerShape(28.dp),\n        tonalElevation = 6.dp,\n        modifier = Modifier.widthIn(min = 280.dp, max = 560.dp)\n    ) {\n        Column(\n            modifier = Modifier.padding(all = 24.dp),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Icon(\n                painter = painterResource(id = iconRes),\n                contentDescription = null\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            Text(\n                text = title,\n                style = MaterialTheme.typography.headlineSmall,\n                color = MaterialTheme.colorScheme.onSurface,\n            )\n            if (summaryText != null) {\n                Spacer(modifier = Modifier.height(16.dp))\n                Text(\n                    text = summaryText,\n                    style = MaterialTheme.typography.bodyMedium,\n                    color = MaterialTheme.colorScheme.onSurfaceVariant,\n                    modifier = Modifier.fillMaxWidth()\n                )\n            }\n            Spacer(modifier = Modifier.height(16.dp))\n            Divider()\n            array.forEach {\n                val interactionSource = remember {\n                    MutableInteractionSource()\n                }\n                Row(\n                    Modifier\n                        .fillMaxWidth()\n                        .height(56.dp)\n                        .selectable(\n                            selected = (it == selectValue),\n                            onClick = { onItemClick(array.indexOf(it)) },\n                            role = Role.RadioButton,\n                            interactionSource = interactionSource,\n                            indication = LocalIndication.current\n                        ),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    RadioButton(\n                        selected = (it == selectValue),\n                        onClick = { onItemClick(array.indexOf(it)) },\n                        interactionSource = interactionSource\n                    )\n                    Text(\n                        text = it,\n                        style = MaterialTheme.typography.bodyLarge,\n                        modifier = Modifier.padding(start = 16.dp)\n                    )\n                }\n            }\n            Divider()\n            Spacer(modifier = Modifier.height(24.dp))\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.End\n            ) {\n                TextButton(\n                    onClick = onCancel\n                ) {\n                    Text(text = stringResource(id = android.R.string.cancel))\n                }\n            }\n        }\n    }\n}\n\n@Composable\nfun EditTextDialog(\n    title: String,\n    summaryText: String,\n    originalValue: String,\n    onDone: (String) -> Unit,\n    onDismissListener: () -> Unit,\n) = Dialog(\n    onDismissRequest = onDismissListener,\n) {\n\n    var inputValue by remember {\n        mutableStateOf(originalValue)\n    }\n\n    Surface(\n        shape = RoundedCornerShape(28.dp),\n        tonalElevation = 6.dp,\n        modifier = Modifier.widthIn(min = 280.dp, max = 560.dp)\n    ) {\n        Column(\n            modifier = Modifier.padding(all = 24.dp),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Icon(\n                painter = painterResource(id = R.drawable.outline_input_24),\n                contentDescription = null\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            Text(\n                text = title,\n                style = MaterialTheme.typography.headlineSmall,\n                color = MaterialTheme.colorScheme.onSurface,\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            Text(\n                text = summaryText,\n                style = MaterialTheme.typography.bodyMedium,\n                color = MaterialTheme.colorScheme.onSurfaceVariant,\n                modifier = Modifier.fillMaxWidth()\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            OutlinedTextField(\n                value = inputValue,\n                onValueChange = {\n                    inputValue = it\n                },\n                placeholder = {\n                    Text(text = stringResource(R.string.input))\n                },\n                keyboardOptions = KeyboardOptions(\n                    keyboardType = KeyboardType.Number,\n                    imeAction = ImeAction.Done\n                ),\n                keyboardActions = KeyboardActions(onDone = { onDone(inputValue) }),\n                modifier = Modifier.fillMaxWidth(),\n                singleLine = true,\n            )\n            Spacer(modifier = Modifier.height(24.dp))\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.End\n            ) {\n                TextButton(\n                    onClick = {\n                        onDone(inputValue)\n                    }\n                ) {\n                    Text(text = stringResource(id = android.R.string.ok))\n                }\n            }\n        }\n    }\n}\n\n@Composable\nfun MutableSelectedDialog(\n    title: String,\n    summaryText: String?,\n    @DrawableRes iconRes: Int = R.drawable.baseline_format_list_bulleted_24,\n    mapValue: Map<String, String>,\n    selectValues: Set<String>,\n    onOk: (Set<String>) -> Unit,\n    onCancel: () -> Unit,\n    onDismissListener: () -> Unit,\n) = Dialog(\n    onDismissRequest = onDismissListener\n) {\n    val array = remember {\n        mapValue.keys.filter {\n            selectValues.contains(it)\n        }.toMutableStateList()\n    }\n    Surface(\n        shape = RoundedCornerShape(28.dp),\n        tonalElevation = 6.dp,\n        modifier = Modifier.widthIn(min = 280.dp, max = 560.dp)\n    ) {\n        Column(\n            modifier = Modifier.padding(all = 24.dp),\n            horizontalAlignment = Alignment.CenterHorizontally\n        ) {\n            Icon(\n                painter = painterResource(id = iconRes),\n                contentDescription = null\n            )\n            Spacer(modifier = Modifier.height(16.dp))\n            Text(\n                text = title,\n                style = MaterialTheme.typography.headlineSmall,\n                color = MaterialTheme.colorScheme.onSurface,\n            )\n            if (summaryText != null) {\n                Spacer(modifier = Modifier.height(16.dp))\n                Text(\n                    text = summaryText,\n                    style = MaterialTheme.typography.bodyMedium,\n                    color = MaterialTheme.colorScheme.onSurfaceVariant,\n                    modifier = Modifier.fillMaxWidth()\n                )\n            }\n            Spacer(modifier = Modifier.height(16.dp))\n            Divider()\n            mapValue.forEach { current ->\n                val interactionSource = remember {\n                    MutableInteractionSource()\n                }\n                val isSelected = array.contains(current.key)\n                Row(\n                    Modifier\n                        .selectable(\n                            selected = isSelected,\n                            onClick = {\n                                if (!isSelected) array.add(current.key)\n                                else array.remove(current.key)\n                            },\n                            interactionSource = interactionSource,\n                            role = Role.Checkbox,\n                            indication = LocalIndication.current\n                        )\n                        .fillMaxWidth()\n                        .height(56.dp),\n                    verticalAlignment = Alignment.CenterVertically\n                ) {\n                    Checkbox(\n                        checked = isSelected,\n                        onCheckedChange = {\n                            if (!isSelected) array.add(current.key)\n                            else array.remove(current.key)\n                        },\n                        interactionSource = interactionSource\n                    )\n                    Text(\n                        text = current.value,\n                        style = MaterialTheme.typography.bodyLarge,\n                        modifier = Modifier.padding(start = 16.dp)\n                    )\n                }\n            }\n            Divider()\n            Spacer(modifier = Modifier.height(24.dp))\n            Row(\n                modifier = Modifier.fillMaxWidth(),\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.End\n            ) {\n                TextButton(\n                    onClick = onCancel\n                ) {\n                    Text(text = stringResource(id = android.R.string.cancel))\n                }\n                Spacer(modifier = Modifier.width(8.dp))\n                TextButton(\n                    onClick = {\n                        onOk(array.toMutableSet())\n                    }\n                ) {\n                    Text(text = stringResource(id = android.R.string.ok))\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/SettingPref.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting\n\nimport android.content.Context\nimport androidx.core.content.edit\nimport androidx.preference.PreferenceManager\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\nimport com.shicheeng.copymanga.util.ThemeMode\nimport com.shicheeng.copymanga.util.booleanFlow\nimport com.shicheeng.copymanga.util.stringFlow\nimport dagger.hilt.android.qualifiers.ApplicationContext\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport javax.inject.Inject\nimport javax.inject.Singleton\n\n@Singleton\nclass SettingPref @Inject constructor(\n    @ApplicationContext private val context: Context,\n) {\n\n    private val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)\n\n    val readerMode: String\n        get() = sharedPreferences.getString(\n            KEY_ORIENTATION_PREF,\n            ReaderMode.NORMAL.name\n        ) ?: ReaderMode.NORMAL.name\n\n    fun setReaderMode(mode: ReaderMode) {\n        sharedPreferences.edit {\n            putString(KEY_ORIENTATION_PREF, mode.name)\n        }\n    }\n\n    val readerModeEntity = arrayOf(\n        ReaderMode.NORMAL.name,\n        ReaderMode.WEBTOON.name,\n        ReaderMode.STANDARD.name\n    )\n\n    val themeModeEntity = arrayOf(\n        ThemeMode.SYSTEM.name,\n        ThemeMode.LIGHT.name,\n        ThemeMode.DARK.name,\n    )\n\n    var useForeignApi: Boolean\n        get() = sharedPreferences.getBoolean(KEY_USE_FOREIGN_API, false)\n        set(value) {\n            sharedPreferences.edit {\n                putBoolean(KEY_USE_FOREIGN_API, value)\n            }\n        }\n\n    var apiSelected: String\n        get() = sharedPreferences.getString(KEY_API_HEADER_SELECT, \"copymanga.net\")\n            ?: \"copymanga.net\"\n        set(value) {\n            sharedPreferences.edit {\n                putString(KEY_API_HEADER_SELECT, value)\n            }\n        }\n\n    private val _hyperTouch: MutableStateFlow<Boolean> =\n        MutableStateFlow(sharedPreferences.getBoolean(\"key_touch_quick\", false))\n    val hyperTouch = _hyperTouch.asStateFlow()\n\n    fun isUseHyperTouch(isUse: Boolean) {\n        sharedPreferences.edit {\n            putBoolean(\"key_touch_quick\", isUse)\n        }\n        _hyperTouch.tryEmit(sharedPreferences.getBoolean(\"key_touch_quick\", false))\n    }\n\n    private val _pauseUpdateDetector: MutableStateFlow<Boolean> =\n        MutableStateFlow(sharedPreferences.getBoolean(\"disable_update\", false))\n    val pauseUpdateDetector = _pauseUpdateDetector.asStateFlow()\n\n    fun isPauseDetectUpdate(isPause: Boolean) {\n        sharedPreferences.edit {\n            putBoolean(\"disable_update\", isPause)\n        }\n        _pauseUpdateDetector.tryEmit(sharedPreferences.getBoolean(\"disable_update\", isPause))\n    }\n\n    val enableComicsUpdate: MutableStateFlow<Boolean> =\n        MutableStateFlow(sharedPreferences.getBoolean(KEY_ENABLE_COMIC_UPDATE, false))\n\n    fun hasKey(key: String): Boolean {\n        return sharedPreferences.contains(key)\n    }\n\n    fun enableComicsUpdateFetch(enable: Boolean) {\n        sharedPreferences.edit {\n            putBoolean(KEY_ENABLE_COMIC_UPDATE, enable)\n        }\n        enableComicsUpdate.tryEmit(sharedPreferences.getBoolean(KEY_ENABLE_COMIC_UPDATE, false))\n    }\n\n    val timeInterval = MutableStateFlow(\n        if (hasKey(KEY_COMIC_UPDATE_TIME)) {\n            sharedPreferences.getInt(KEY_COMIC_UPDATE_TIME, 6)\n        } else {\n            6\n        }\n    )\n\n    fun editTimeInterval(time: Int) {\n        sharedPreferences.edit {\n            putInt(KEY_COMIC_UPDATE_TIME, time)\n        }\n        timeInterval.tryEmit(sharedPreferences.getInt(KEY_COMIC_UPDATE_TIME, 6))\n    }\n\n    val updateConstant = MutableStateFlow(\n        if (hasKey(KEY_COMIC_UPDATE_CONS)) {\n            sharedPreferences.getStringSet(KEY_COMIC_UPDATE_CONS, setOf(IN_WIFI)) ?: setOf(IN_WIFI)\n        } else {\n            setOf(IN_WIFI)\n        }\n    )\n\n    fun changeUpdateConstant(value: Set<String>) {\n        sharedPreferences.edit {\n            putStringSet(KEY_COMIC_UPDATE_CONS, value)\n        }\n        updateConstant.tryEmit(\n            sharedPreferences.getStringSet(\n                KEY_COMIC_UPDATE_CONS,\n                setOf(IN_WIFI)\n            ) ?: setOf(IN_WIFI)\n        )\n    }\n\n\n    var appThemeMode\n        get() = sharedPreferences.getString(KEY_APP_THEME, ThemeMode.SYSTEM.name)\n            ?: ThemeMode.SYSTEM.name\n        set(value) {\n            sharedPreferences.edit {\n                putString(KEY_APP_THEME, value)\n            }\n        }\n\n    var cutoutDisplay\n        get() = sharedPreferences.getBoolean(KEY_CUTOUT_DISPLAY, true)\n        set(value) {\n            sharedPreferences.edit {\n                putBoolean(KEY_CUTOUT_DISPLAY, value)\n            }\n        }\n\n    var cacheSize\n        get() = sharedPreferences.getString(KEY_CACHE_SIZE, \"400\") ?: \"400\"\n        set(value) {\n            sharedPreferences.edit {\n                putString(KEY_CACHE_SIZE, value)\n            }\n        }\n\n\n    val loginPerson\n        get() = sharedPreferences.getString(KEY_LOGIN_STATUS, null)\n\n    val loginPersonalFlow\n        get() = sharedPreferences.stringFlow(KEY_LOGIN_STATUS)\n\n    fun selectedUUId(uuid: String?) {\n        sharedPreferences.edit {\n            putString(KEY_LOGIN_STATUS, uuid)\n        }\n    }\n\n    val webReadPoint\n        get() = sharedPreferences.getBoolean(\n            KEY_ENABLE_WEB_READ_POINT,\n            false\n        )\n\n\n    val webReadPointFlow\n        get() = sharedPreferences.booleanFlow(KEY_ENABLE_WEB_READ_POINT)\n\n\n    fun enableWebReadPoint(boolean: Boolean) {\n        sharedPreferences.edit {\n            putBoolean(KEY_ENABLE_WEB_READ_POINT, boolean)\n        }\n    }\n\n\n    var downloadOnlyOnWifi\n        get() = sharedPreferences.getBoolean(KEY_DOWNLOAD_ONLY_ON_WIFI, true)\n        set(value) {\n            sharedPreferences.edit {\n                putBoolean(KEY_DOWNLOAD_ONLY_ON_WIFI, value)\n            }\n        }\n\n    val downloadOnlyOnWifiFlow = sharedPreferences.booleanFlow(KEY_DOWNLOAD_ONLY_ON_WIFI)\n\n\n    companion object {\n        const val KEY_ENABLE_COMIC_UPDATE = \"KEY_ENABLE_COMIC_UPDATE\"\n        const val KEY_COMIC_UPDATE_TIME = \"KEY_COMIC_UPDATE_TIME\"\n        const val KEY_COMIC_UPDATE_CONS = \"KEY_COMIC_UPDATE_CONS\"\n        const val KEY_APP_THEME = \"KEY_APP_THEME\"\n        const val KEY_CUTOUT_DISPLAY = \"KEY_CUTOUT_DISPLAY\"\n        const val KEY_CACHE_SIZE = \"KEY_CACHE_SIZE\"\n        const val KEY_LOGIN_STATUS = \"KEY_LOGIN_STATUS\"\n        const val KEY_ENABLE_WEB_READ_POINT = \"KEY_ENABLE_WEB_READ_POINT\"\n        const val KEY_DOWNLOAD_ONLY_ON_WIFI = \"KEY_WIFI_DOWNLOAD\"\n        const val KEY_ORIENTATION_PREF = \"pref_orientation_key\"\n        const val KEY_USE_FOREIGN_API = \"pref_is_use_foreign_api\"\n        const val KEY_API_HEADER_SELECT = \"key_api_header_select\"\n    }\n\n\n}\n\n\nconst val IN_WIFI = \"IN_WIFI\"\nconst val IN_CHARGING = \"IN_CHARGING\"\nconst val IN_BATTERY_NOT_LOW = \"IN_BATTERY_NOT_LOW\"\n\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/SettingViewModel.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\nimport com.shicheeng.copymanga.resposity.LoginRepository\nimport com.shicheeng.copymanga.server.download.woker.DownloadedWorker\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.filterNotNull\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass SettingViewModel @Inject constructor(\n    private val settingPref: SettingPref,\n    private val repository: LoginRepository,\n    private val callWorker: DownloadedWorker.Caller,\n) : ViewModel() {\n\n    private val _readerMode = MutableStateFlow(settingPref.readerMode)\n    val readerMode = _readerMode.asStateFlow()\n\n    private val _useForeignRequest = MutableStateFlow(settingPref.useForeignApi)\n    val useForeignRequest = _useForeignRequest.asStateFlow()\n\n    private val _apiSelected = MutableStateFlow(settingPref.apiSelected)\n    val apiSelected = _apiSelected.asStateFlow()\n\n    val isTurn = settingPref.enableComicsUpdate.asStateFlow()\n    val timeInterval = settingPref.timeInterval.asStateFlow()\n    val updateConstants = settingPref.updateConstant.asStateFlow()\n    private val _themeModeName = MutableStateFlow(settingPref.appThemeMode)\n    val themeModeName = _themeModeName.asStateFlow()\n\n    private val _cutoutDisplay = MutableStateFlow(settingPref.cutoutDisplay)\n    val cutoutDisplay = _cutoutDisplay.asStateFlow()\n\n    private val _cacheSize = MutableStateFlow(settingPref.cacheSize)\n    val cacheSize = _cacheSize.asStateFlow()\n\n    val webPoint = settingPref.webReadPointFlow\n        .stateIn(\n            scope = viewModelScope,\n            initialValue = settingPref.webReadPoint,\n            started = SharingStarted.Eagerly\n        )\n    val onlyInWifi = settingPref.downloadOnlyOnWifiFlow\n        .stateIn(\n            scope = viewModelScope,\n            started = SharingStarted.Eagerly,\n            initialValue = settingPref.downloadOnlyOnWifi\n        )\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val name = settingPref.loginPersonalFlow\n        .stateIn(\n            started = SharingStarted.Eagerly,\n            scope = viewModelScope,\n            initialValue = settingPref.loginPerson\n        )\n        .filter { !it.isNullOrBlank() || !it.isNullOrEmpty() }\n        .filterNotNull()\n        .flatMapLatest {\n            repository.getUserByUUid(it)\n        }.stateIn(\n            scope = viewModelScope,\n            started = SharingStarted.Eagerly,\n            initialValue = null\n        )\n\n\n    fun setReaderMode(readerMode: ReaderMode) {\n        settingPref.setReaderMode(readerMode)\n        _readerMode.tryEmit(settingPref.readerMode)\n    }\n\n    fun setThemeMode(themeModeName: String) {\n        settingPref.appThemeMode = themeModeName\n        _themeModeName.tryEmit(settingPref.appThemeMode)\n    }\n\n    fun isUseForeignRequest(isUse: Boolean) {\n        settingPref.useForeignApi = isUse\n        _useForeignRequest.tryEmit(settingPref.useForeignApi)\n    }\n\n    fun selectApi(api: String) {\n        settingPref.apiSelected = api\n        _apiSelected.tryEmit(settingPref.apiSelected)\n    }\n\n    fun switchCutoutDisplay(enable: Boolean) = viewModelScope.launch {\n        settingPref.cutoutDisplay = enable\n        _cutoutDisplay.emit(settingPref.cutoutDisplay)\n    }\n\n    fun setCacheSize(size: String) = viewModelScope.launch {\n        settingPref.cacheSize = size\n        _cacheSize.emit(size)\n    }\n\n    fun changeDownloadConstants(onlyWifi: Boolean) = viewModelScope.launch {\n        settingPref.downloadOnlyOnWifi = onlyWifi\n        callWorker.updateConstraints()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/about/About.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting.about\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.Badge\nimport androidx.compose.material3.BadgedBox\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.HorizontalDivider\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.ListItem\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.LocalTextStyle\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedCard\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.contentColorFor\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.dp\nimport coil.compose.rememberAsyncImagePainter\nimport com.mikepenz.aboutlibraries.Libs\nimport com.mikepenz.aboutlibraries.entity.Library\nimport com.mikepenz.aboutlibraries.util.author\nimport com.mikepenz.aboutlibraries.util.withContext\nimport com.shicheeng.copymanga.BuildConfig\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.VerticalFastScroller\nimport com.shicheeng.copymanga.util.openUrl\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun AboutScreen(\n    onBack: () -> Unit,\n) {\n\n    val content = LocalContext.current\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val libs = remember(Libs.Builder().withContext(content).build()::libraries)\n    val thankfulApps = rememberThankfulApps()\n    val lazyState = rememberLazyListState()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(id = R.string.about))\n                },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onBack\n                    )\n                },\n                scrollBehavior = topAppBarScrollBehavior\n            )\n        }\n    ) { paddingValues ->\n        VerticalFastScroller(\n            listState = lazyState,\n            topContentPadding = paddingValues.calculateTopPadding()\n        ) {\n            LazyColumn(\n                contentPadding = paddingValues,\n                verticalArrangement = Arrangement.spacedBy(8.dp),\n                modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),\n                state = lazyState\n            ) {\n                item {\n                    AboutScreenHeader()\n                }\n                item {\n                    Text(\n                        text = stringResource(R.string.thankful_app),\n                        modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),\n                        color = MaterialTheme.colorScheme.primary\n                    )\n                }\n                items(thankfulApps) { aboutUiModel ->\n                    ListItem(\n                        headlineContent = {\n                            Text(text = aboutUiModel.name)\n                        },\n                        supportingContent = {\n                            Text(text = aboutUiModel.description)\n                        },\n                        leadingContent = {\n                            Icon(\n                                painter = rememberAsyncImagePainter(model = aboutUiModel.url),\n                                contentDescription = null\n                            )\n                        },\n                        modifier = Modifier.clickable {\n                            content openUrl aboutUiModel.url\n                        }\n                    )\n                }\n                item {\n                    Text(\n                        text = stringResource(R.string.open_source),\n                        modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),\n                        color = MaterialTheme.colorScheme.primary\n                    )\n                }\n                items(libs) { library ->\n                    AboutListItem(library = library)\n                }\n                item {\n                    Text(\n                        text = stringResource(R.string.general_warning),\n                        style = MaterialTheme.typography.labelMedium,\n                        color = MaterialTheme.colorScheme.onSurfaceVariant\n                    )\n                }\n            }\n        }\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun AboutScreenHeader() {\n\n    val backgroundColor = MaterialTheme.colorScheme.secondaryContainer\n    val density = LocalDensity.current\n\n    Column(\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(16.dp),\n        horizontalAlignment = Alignment.CenterHorizontally\n    ) {\n        Image(\n            contentDescription = \"logo\",\n            painter = painterResource(id = R.mipmap.ic_copy_foreground),\n            modifier = Modifier\n                .drawWithContent {\n                    drawCircle(\n                        color = backgroundColor,\n                        radius = with(density) {\n                            130\n                                .toDp()\n                                .toPx()\n                        }\n                    )\n                    drawContent()\n                },\n            colorFilter = ColorFilter\n                .tint(color = contentColorFor(backgroundColor = backgroundColor))\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        BadgedBox(\n            badge = {\n                Badge(\n                    containerColor = MaterialTheme.colorScheme.primary,\n                    contentColor = MaterialTheme.colorScheme.onPrimary\n                ) {\n                    Text(text = BuildConfig.VERSION_NAME)\n                }\n            }\n        ) {\n            Text(\n                text = stringResource(id = R.string.app_name),\n                style = MaterialTheme.typography.titleLarge\n            )\n        }\n\n        Spacer(modifier = Modifier.height(2.dp))\n        Text(\n            text = stringResource(R.string.copy_manga_summary),\n            modifier = Modifier.padding(horizontal = 16.dp),\n            style = MaterialTheme.typography.titleSmall,\n            color = MaterialTheme.colorScheme.onSurfaceVariant\n        )\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun AboutListItem(\n    library: Library,\n) {\n    val name = remember { library.licenses.takeIf { it.isNotEmpty() }?.first()?.name }\n    val context = LocalContext.current\n    OutlinedCard(\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(horizontal = 16.dp),\n        onClick = {\n            library.website?.let {\n                context openUrl it\n            }\n        }\n    ) {\n        Column(\n            modifier = Modifier.padding(16.dp)\n        ) {\n            Row(\n                verticalAlignment = Alignment.CenterVertically,\n                horizontalArrangement = Arrangement.Center\n            ) {\n                Icon(\n                    painter = painterResource(\n                        id = when {\n                            name?.contains(\"MIT\", ignoreCase = true) == true -> {\n                                R.drawable.legal_license_mit_svgrepo_com\n                            }\n\n                            name?.contains(\"Apache\", ignoreCase = true) == true -> {\n                                R.drawable.apache_svgrepo_com\n                            }\n\n                            else -> {\n                                R.drawable.open_source_fill_svgrepo_com\n                            }\n                        }\n                    ),\n                    contentDescription = null,\n                    modifier = Modifier\n                        .padding(8.dp)\n                        .size(32.dp)\n                )\n                Column(\n                    modifier = Modifier.padding(bottom = 4.dp),\n                    verticalArrangement = Arrangement.Center\n                ) {\n                    Text(\n                        text = library.name,\n                        style = MaterialTheme.typography.titleMedium\n                    )\n                    Text(\n                        text = library.author.ifBlank { stringResource(id = android.R.string.unknownName) },\n                        style = MaterialTheme.typography.bodyMedium,\n                        color = MaterialTheme.colorScheme.onSurfaceVariant\n                    )\n                }\n            }\n            HorizontalDivider()\n            Text(\n                text = library.description ?: stringResource(id = android.R.string.unknownName),\n                style = MaterialTheme.typography.bodyMedium,\n                modifier = Modifier.padding(vertical = 8.dp)\n            )\n            Row(\n                modifier = Modifier\n                    .fillMaxWidth()\n            ) {\n                CompositionLocalProvider(\n                    LocalTextStyle provides MaterialTheme.typography.labelSmall,\n                    LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant\n                ) {\n                    Text(\n                        text = library.licenses.takeIf { it.isNotEmpty() }\n                            ?.joinToString { it.name }\n                            ?: stringResource(id = android.R.string.unknownName),\n                        modifier = Modifier.padding(end = 16.dp),\n                        maxLines = 1,\n                        overflow = TextOverflow.Ellipsis\n                    )\n                    Spacer(modifier = Modifier.weight(1f))\n                    Text(\n                        text = library.artifactVersion\n                            ?: stringResource(id = android.R.string.unknownName)\n                    )\n                }\n\n            }\n        }\n\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/about/AboutDatas.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting.about\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\n\n\n@Composable\nfun rememberThankfulApps() = remember {\n    listOf(\n        AboutDataUiModel(\n            name = \"Tachiyomi\",\n            url = \"tachiyomi.org\",\n            description = \"Free and open source manga reader for Android.\",\n            author = \"tachiyomiorg\",\n            license = ApacheLicense,\n            iconUrl = \"https://tachiyomi.org/img/logo-128px.png\"\n        ),\n        AboutDataUiModel(\n            name = \"Kotatsu\",\n            description = \"Manga reader for Android\",\n            author = \"KotatsuApp\",\n            license = GPLv3License,\n            url = \"https://kotatsu.app/\",\n            iconUrl = \"https://kotatsu.app/logo-compact.svg\"\n        ),\n        AboutDataUiModel(\n            name = \"copymanga 拷贝漫画\",\n            description = \"拷贝漫画的第三方APP，优化阅读/下载体验\",\n            author = \"fumiama\",\n            license = GPLv3License,\n            url = \"https://github.com/fumiama/copymanga\",\n            iconUrl = \"https://raw.githubusercontent.com/fumiama/copymanga/main/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png\"\n        ),\n        AboutDataUiModel(\n            name = \"copymanga-downloader\",\n            description = \"使用python编译exe/bash/命令行参数来下载copymanga(拷贝漫画)中的漫画，支持批量+选话下载和获取您收藏的漫画并下载！(windows&linux支持，MacOS代码支持)\",\n            url = \"https://github.com/misaka10843/copymanga-downloader\",\n            author = \"misaka10843\",\n            license = GPLv3License\n        )\n    )\n}\n\ndata class AboutDataUiModel(\n    val name: String,\n    val url: String,\n    val iconUrl: String? = null,\n    val description: String,\n    val author: String,\n    val license: String,\n)\n\nprivate const val GPLv3License = \"GNU General Public License v3.0\"\nprivate const val ApacheLicense = \"Apache License 2.0\""
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/setting/worker/Worker.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.setting.worker\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.items\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.lifecycle.asFlow\nimport androidx.work.WorkInfo\nimport androidx.work.WorkManager\nimport androidx.work.WorkQuery\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.theme.MonospaceStyle\nimport com.shicheeng.copymanga.util.copyComposable\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun WorkerScreen(\n    onBack: () -> Unit,\n) {\n    val context = LocalContext.current\n    val workManager = WorkManager.getInstance(context)\n    val successWork by workManager\n        .getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.SUCCEEDED))\n        .asFlow()\n        .collectAsState(initial = emptyList())\n    val enqueueWord by workManager\n        .getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.ENQUEUED))\n        .asFlow()\n        .collectAsState(initial = emptyList())\n    val runningWork by workManager\n        .getWorkInfosLiveData(WorkQuery.fromStates(WorkInfo.State.RUNNING))\n        .asFlow()\n        .collectAsState(initial = emptyList())\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(id = R.string.work_information))\n                },\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onBack\n                    )\n                }\n            )\n        },\n        modifier = Modifier.fillMaxSize()\n    ) { paddingValues ->\n        LazyColumn(\n            contentPadding = paddingValues.copyComposable(\n                start = 16.dp,\n                end = 16.dp,\n                top = 16.dp + paddingValues.calculateTopPadding(),\n                bottom = 16.dp + paddingValues.calculateBottomPadding()\n            ),\n            verticalArrangement = Arrangement.spacedBy(16.dp),\n        ) {\n            item {\n                Text(text = stringResource(R.string.successed))\n            }\n            items(successWork) {\n                Text(\n                    text = it.tags.joinToString(),\n                    style = MonospaceStyle\n                )\n                Text(\n                    text = it.id.toString(),\n                    style = MonospaceStyle\n                )\n                Text(\n                    text = it.state.name,\n                    style = MonospaceStyle\n                )\n            }\n            item {\n                Text(text = stringResource(R.string.running))\n            }\n            items(runningWork) {\n                Text(\n                    text = it.tags.joinToString(),\n                    style = MonospaceStyle\n                )\n                Text(\n                    text = it.id.toString(),\n                    style = MonospaceStyle\n                )\n                Text(\n                    text = it.state.name,\n                    style = MonospaceStyle\n                )\n            }\n            item {\n                Text(text = stringResource(R.string.enqueue))\n            }\n            items(enqueueWord) {\n                Text(\n                    text = it.tags.joinToString(),\n                    style = MonospaceStyle\n                )\n                Text(\n                    text = it.id.toString(),\n                    style = MonospaceStyle\n                )\n                Text(\n                    text = it.state.name,\n                    style = MonospaceStyle\n                )\n            }\n        }\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/topiclist/TopicListScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.topiclist\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport androidx.paging.compose.itemContentType\nimport androidx.paging.compose.itemKey\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.topicalllist.TopicAllListItem\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.main.home.HomePageTopicCard\nimport com.shicheeng.copymanga.util.copyComposable\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun TopicListScreen(\n    viewModel: TopicListVIewModel = hiltViewModel(),\n    onBack: () -> Unit,\n    onTopicClick: (TopicAllListItem) -> Unit,\n) {\n\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val list = viewModel.list.collectAsLazyPagingItems()\n\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = { Text(text = stringResource(id = R.string.topic)) },\n                scrollBehavior = topAppBarScrollBehavior,\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onBack\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n        LazyColumn(\n            contentPadding = paddingValues.copyComposable(\n                start = 16.dp,\n                end = 16.dp\n            ),\n            modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),\n            verticalArrangement = Arrangement.spacedBy(16.dp)\n        ) {\n            items(\n                count = list.itemCount,\n                key = list.itemKey { it.pathWord },\n                contentType = list.itemContentType { it.pathWord }\n            ) { index ->\n                list[index]?.let {\n                    HomePageTopicCard(\n                        title = it.title,\n                        supportedText = it.brief,\n                        subText = it.period,\n                        imageUrl = it.cover,\n                        modifier = Modifier.fillMaxWidth()\n                    ) {\n                        onTopicClick(it)\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/topiclist/TopicListVIewModel.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.topiclist\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.domin.CopyMangaApi\nimport com.shicheeng.copymanga.pagingsource.MangaTopicListPagingSource\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport javax.inject.Inject\n\n@HiltViewModel\nclass TopicListVIewModel @Inject constructor(\n    copyMangaApi: CopyMangaApi,\n) : ViewModel() {\n\n    val list = Pager(config = PagingConfig(pageSize = 1)) {\n        MangaTopicListPagingSource(copyMangaApi)\n    }.flow.cachedIn(viewModelScope)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/topics/TopicComicItem.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.topics\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.LocalContentColor\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.OutlinedCard\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.res.painterResource\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.topiclist.TopicItem\nimport com.shicheeng.copymanga.util.formNumberToRead\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun TopicComicItem(\n    topicItem: TopicItem,\n    onItemClick: (TopicItem) -> Unit,\n) {\n    OutlinedCard(\n        modifier = Modifier\n            .fillMaxWidth()\n            .padding(horizontal = 16.dp, vertical = 8.dp),\n        onClick = {\n            onItemClick(topicItem)\n        }\n    ) {\n        Row(\n            modifier = Modifier.fillMaxWidth()\n        ) {\n            AsyncImage(\n                model = topicItem.cover,\n                contentDescription = null,\n                modifier = Modifier\n                    .width(100.dp)\n                    .padding(8.dp)\n                    .clip(MaterialTheme.shapes.medium)\n                    .aspectRatio(2f / 3f),\n                contentScale = ContentScale.Crop,\n                placeholder = ColorPainter(MaterialTheme.colorScheme.secondaryContainer)\n            )\n            Column(\n                modifier = Modifier\n                    .weight(1f)\n                    .padding(vertical = 8.dp)\n            ) {\n                Text(\n                    text = topicItem.name,\n                    style = MaterialTheme.typography.titleMedium,\n                    color = MaterialTheme.colorScheme.onSurface\n                )\n                Spacer(modifier = Modifier.height(4.dp))\n                Text(\n                    text = topicItem.author.joinToString { it.name },\n                    style = MaterialTheme.typography.titleSmall,\n                    color = MaterialTheme.colorScheme.secondary\n                )\n                Text(\n                    text = topicItem.theme.joinToString { it.name },\n                    style = MaterialTheme.typography.labelMedium,\n                    color = MaterialTheme.colorScheme.onSurfaceVariant\n                )\n                Row(\n                    verticalAlignment = Alignment.CenterVertically,\n                    modifier = Modifier.padding(top = 4.dp)\n                ) {\n                    CompositionLocalProvider(\n                        LocalContentColor provides MaterialTheme.colorScheme.tertiary\n                    ) {\n                        Icon(\n                            painter = painterResource(id = R.drawable.ic_trend_up),\n                            contentDescription = null,\n                            modifier = Modifier.size(12.dp)\n                        )\n                        Text(\n                            text = topicItem.popular.toLong().formNumberToRead(),\n                            style = MaterialTheme.typography.labelSmall,\n                            modifier = Modifier.padding(start = 4.dp)\n                        )\n                    }\n                }\n            }\n        }\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/topics/TopicHeader.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.topics\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.aspectRatio\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.graphics.painter.ColorPainter\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport coil.compose.AsyncImage\n\n@Composable\nfun TopicHeader(\n    title: String,\n    coverUrl: String,\n    period: String,\n    time: String,\n    createTime: String,\n) {\n    Column(\n        modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp)\n    ) {\n        AsyncImage(\n            model = coverUrl,\n            contentDescription = null,\n            modifier = Modifier\n                .clip(MaterialTheme.shapes.extraLarge)\n                .aspectRatio(5f / 3f),\n            placeholder = ColorPainter(MaterialTheme.colorScheme.secondary),\n            contentScale = ContentScale.Crop\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        Text(\n            text = title,\n            style = MaterialTheme.typography.headlineLarge,\n            modifier = Modifier\n                .fillMaxWidth()\n                .padding(horizontal = 16.dp),\n            textAlign = TextAlign.Center\n        )\n        Text(\n            text = \"$period • $time • $createTime\",\n            style = MaterialTheme.typography.labelLarge,\n            modifier = Modifier.fillMaxWidth(),\n            textAlign = TextAlign.Center,\n            maxLines = 1\n        )\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/topics/TopicHeaderKeys.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.topics\n\nenum class TopicHeaderKeys {\n    HEADER,SUMMARY\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/topics/TopicScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.topics\n\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.material3.surfaceColorAtElevation\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.alpha\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport androidx.paging.compose.itemContentType\nimport androidx.paging.compose.itemKey\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.util.copyComposable\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun TopicsScreen(\n    topicViewModel: TopicViewModel = hiltViewModel(),\n    onBack: () -> Unit,\n    onItemClick: (pathWord: String) -> Unit,\n) {\n    val uiState by topicViewModel.uiState.collectAsState()\n    val list = topicViewModel.list.collectAsLazyPagingItems()\n\n    if (uiState == UIState.Loading) {\n        LoadingScreen()\n        return\n    }\n    if (uiState is UIState.Error<*>) {\n        ErrorScreen(\n            errorMessage = (uiState as UIState.Error<*>)\n                .errorMessage\n                .message\n                ?: stringResource(id = R.string.error)\n        ) {\n            topicViewModel.retry()\n            list.refresh()\n        }\n        return\n    }\n    val successUIState = uiState as UIState.Success\n    val lazyListState = rememberLazyListState()\n\n    Scaffold(\n        topBar = {\n            val firstVisibleItemIndex by remember {\n                derivedStateOf { lazyListState.firstVisibleItemIndex }\n            }\n            val firstVisibleItemScrollOffset by remember {\n                derivedStateOf { lazyListState.firstVisibleItemScrollOffset }\n            }\n            val animatedTitleAlpha by animateFloatAsState(\n                if (firstVisibleItemIndex > 0) 1f else 0f, label = \"animated_title_alpha\",\n            )\n            val animatedBgAlpha by animateFloatAsState(\n                if (firstVisibleItemIndex > 0 || firstVisibleItemScrollOffset > 0) 1f else 0f,\n                label = \"animated_background_alpha\",\n            )\n            TopAppBar(\n                title = {\n                    Text(\n                        text = stringResource(R.string.topic_detail_text),\n                        modifier = Modifier.alpha(animatedTitleAlpha)\n                    )\n                },\n                colors = TopAppBarDefaults.topAppBarColors(\n                    containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp)\n                        .copy(alpha = animatedBgAlpha)\n                ),\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = onBack\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n        LazyColumn(\n            contentPadding = paddingValues.copyComposable(\n                top = 0.dp\n            ),\n            state = lazyListState\n        ) {\n            item(\n                key = TopicHeaderKeys.HEADER,\n                contentType = TopicHeaderKeys.HEADER\n            ) {\n                TopicHeader(\n                    title = successUIState.content.results.title,\n                    coverUrl = successUIState.content.results.cover,\n                    period = successUIState.content.results.period,\n                    time = successUIState.content.results.journal,\n                    createTime = successUIState.content.results.datetimeCreated\n                )\n            }\n            item(\n                key = TopicHeaderKeys.SUMMARY,\n                contentType = TopicHeaderKeys.SUMMARY\n            ) {\n                Text(\n                    text = successUIState.content.results.brief,\n                    style = MaterialTheme.typography.bodyLarge,\n                    modifier = Modifier\n                        .fillMaxWidth()\n                        .padding(horizontal = 16.dp),\n                    textAlign = TextAlign.Start\n                )\n            }\n            items(\n                count = list.itemCount,\n                contentType = list.itemContentType { it.pathWord },\n                key = list.itemKey { it.pathWord }\n            ) { index ->\n                list[index]?.let { topicItem ->\n                    TopicComicItem(topicItem = topicItem) {\n                        onItemClick(it.pathWord)\n                    }\n                }\n            }\n            pagingLoadingIndication(\n                loadState = list.loadState.append\n            ) {\n                list.retry()\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/topics/TopicViewModel.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.topics\n\nimport androidx.lifecycle.SavedStateHandle\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.resposity.MangaTopicDetailRepository\nimport com.shicheeng.copymanga.util.RetryTrigger\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.util.retryableFlow\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.FlowPreview\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.filterNotNull\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport javax.inject.Inject\n\n@OptIn(FlowPreview::class)\n@HiltViewModel\nclass TopicViewModel @Inject constructor(\n    savedStateHandle: SavedStateHandle,\n    private val mangaTopicDetailRepository: MangaTopicDetailRepository,\n) : ViewModel() {\n\n    private val _pathWord: MutableStateFlow<String?> = MutableStateFlow(savedStateHandle[\"pathWord\"])\n    private val type: Int = savedStateHandle[\"type\"] ?: 1\n    private val _retryTiger = RetryTrigger()\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val list = _pathWord\n        .filterNotNull()\n        .flatMapLatest {\n            mangaTopicDetailRepository.mangas(it, type)\n        }.cachedIn(viewModelScope)\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val uiState = retryableFlow(_retryTiger) {\n        _pathWord\n            .filterNotNull()\n            .flatMapLatest {\n                mangaTopicDetailRepository.load(it)\n            }\n    }\n        .stateIn(\n            scope = viewModelScope,\n            started = SharingStarted.Eagerly,\n            initialValue = UIState.Loading\n        )\n\n\n    fun retry() = _retryTiger.retry()\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/screen/webshelf/WebShelfScreen.kt",
    "content": "package com.shicheeng.copymanga.ui.screen.webshelf\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.lazy.grid.GridCells\nimport androidx.compose.foundation.lazy.grid.LazyVerticalGrid\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.material.pullrefresh.rememberPullRefreshState\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.res.stringResource\nimport androidx.compose.ui.unit.dp\nimport androidx.hilt.navigation.compose.hiltViewModel\nimport androidx.paging.LoadState\nimport androidx.paging.compose.collectAsLazyPagingItems\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.ui.screen.compoents.ErrorScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.LoadingScreen\nimport com.shicheeng.copymanga.ui.screen.compoents.PlainButton\nimport com.shicheeng.copymanga.ui.screen.compoents.RefreshLayout\nimport com.shicheeng.copymanga.ui.screen.compoents.pagingLoadingIndication\nimport com.shicheeng.copymanga.ui.screen.list.CommonListItem\nimport com.shicheeng.copymanga.util.copyComposable\nimport com.shicheeng.copymanga.viewmodel.WebShelfViewModel\nimport retrofit2.HttpException\n\n@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)\n@Composable\nfun WebShelfScreen(\n    webShelfViewModel: WebShelfViewModel = hiltViewModel(),\n    navClick: () -> Unit,\n    reLoginClick: () -> Unit,\n    onPathWord: (String) -> Unit,\n) {\n    val data = webShelfViewModel.data.collectAsLazyPagingItems()\n    val topAppBarScrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()\n    val pullRefreshState = rememberPullRefreshState(\n        refreshing = data.loadState.refresh is LoadState.Loading,\n        onRefresh = data::refresh\n    )\n\n\n    if (data.loadState.refresh is LoadState.Loading) {\n        LoadingScreen()\n        return\n    }\n\n    if (data.loadState.refresh is LoadState.Error) {\n        val error = (data.loadState.refresh as LoadState.Error).error\n        ErrorScreen(\n            errorMessage = error.message ?: \"\",\n            onTry = data::refresh,\n            needSecondaryText = error is HttpException && error.code() == 401,\n            secondaryText = stringResource(id = R.string.re_login),\n            onSecondaryClick = reLoginClick\n        )\n        return\n    }\n    Scaffold(\n        topBar = {\n            TopAppBar(\n                title = {\n                    Text(text = stringResource(id = R.string.shelf_cloud))\n                },\n                scrollBehavior = topAppBarScrollBehavior,\n                navigationIcon = {\n                    PlainButton(\n                        id = R.string.back_to_up,\n                        drawableRes = R.drawable.ic_arrow_back,\n                        onButtonClick = navClick\n                    )\n                }\n            )\n        }\n    ) { paddingValues ->\n\n        RefreshLayout(\n            pullRefreshState = pullRefreshState,\n            isRefreshing = data.loadState.refresh is LoadState.Loading,\n            topPadding = paddingValues.calculateTopPadding()\n        ) {\n            LazyVerticalGrid(\n                contentPadding = paddingValues.copyComposable(\n                    start = 16.dp,\n                    end = 16.dp\n                ),\n                columns = GridCells.Fixed(3),\n                verticalArrangement = Arrangement.spacedBy(16.dp),\n                horizontalArrangement = Arrangement.spacedBy(16.dp),\n                modifier = Modifier.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection)\n            ) {\n                items(data.itemCount) { index ->\n                    data[index]?.let { item ->\n                        CommonListItem(\n                            url = item.comic.cover,\n                            title = item.comic.name,\n                            author = item.comic.author.joinToString { it.name }\n                        ) {\n                            onPathWord(item.comic.pathWord)\n                        }\n                    }\n                }\n                pagingLoadingIndication(\n                    loadState = data.loadState.refresh,\n                    onTry = data::retry\n                )\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/theme/Color.kt",
    "content": "package com.shicheeng.copymanga.ui.theme\n\nimport androidx.compose.ui.graphics.Color\n\nval primaryLight = Color(0xFF3C6090)\nval onPrimaryLight = Color(0xFFFFFFFF)\nval primaryContainerLight = Color(0xFFD4E3FF)\nval onPrimaryContainerLight = Color(0xFF001C3A)\nval secondaryLight = Color(0xFF545F71)\nval onSecondaryLight = Color(0xFFFFFFFF)\nval secondaryContainerLight = Color(0xFFD8E3F8)\nval onSecondaryContainerLight = Color(0xFF111C2B)\nval tertiaryLight = Color(0xFF6D5676)\nval onTertiaryLight = Color(0xFFFFFFFF)\nval tertiaryContainerLight = Color(0xFFF7D8FF)\nval onTertiaryContainerLight = Color(0xFF271430)\nval errorLight = Color(0xFFBA1A1A)\nval onErrorLight = Color(0xFFFFFFFF)\nval errorContainerLight = Color(0xFFFFDAD6)\nval onErrorContainerLight = Color(0xFF410002)\nval backgroundLight = Color(0xFFF9F9FF)\nval onBackgroundLight = Color(0xFF191C20)\nval surfaceLight = Color(0xFFF9F9FF)\nval onSurfaceLight = Color(0xFF191C20)\nval surfaceVariantLight = Color(0xFFE0E2EC)\nval onSurfaceVariantLight = Color(0xFF43474E)\nval outlineLight = Color(0xFF74777F)\nval outlineVariantLight = Color(0xFFC3C6CF)\nval scrimLight = Color(0xFF000000)\nval inverseSurfaceLight = Color(0xFF2E3035)\nval inverseOnSurfaceLight = Color(0xFFF0F0F7)\nval inversePrimaryLight = Color(0xFFA5C8FF)\nval surfaceDimLight = Color(0xFFD9DAE0)\nval surfaceBrightLight = Color(0xFFF9F9FF)\nval surfaceContainerLowestLight = Color(0xFFFFFFFF)\nval surfaceContainerLowLight = Color(0xFFF2F3FA)\nval surfaceContainerLight = Color(0xFFEDEDF4)\nval surfaceContainerHighLight = Color(0xFFE7E8EE)\nval surfaceContainerHighestLight = Color(0xFFE1E2E9)\n\nval primaryLightMediumContrast = Color(0xFF1D4472)\nval onPrimaryLightMediumContrast = Color(0xFFFFFFFF)\nval primaryContainerLightMediumContrast = Color(0xFF5376A7)\nval onPrimaryContainerLightMediumContrast = Color(0xFFFFFFFF)\nval secondaryLightMediumContrast = Color(0xFF394354)\nval onSecondaryLightMediumContrast = Color(0xFFFFFFFF)\nval secondaryContainerLightMediumContrast = Color(0xFF6B7588)\nval onSecondaryContainerLightMediumContrast = Color(0xFFFFFFFF)\nval tertiaryLightMediumContrast = Color(0xFF513B59)\nval onTertiaryLightMediumContrast = Color(0xFFFFFFFF)\nval tertiaryContainerLightMediumContrast = Color(0xFF856C8D)\nval onTertiaryContainerLightMediumContrast = Color(0xFFFFFFFF)\nval errorLightMediumContrast = Color(0xFF8C0009)\nval onErrorLightMediumContrast = Color(0xFFFFFFFF)\nval errorContainerLightMediumContrast = Color(0xFFDA342E)\nval onErrorContainerLightMediumContrast = Color(0xFFFFFFFF)\nval backgroundLightMediumContrast = Color(0xFFF9F9FF)\nval onBackgroundLightMediumContrast = Color(0xFF191C20)\nval surfaceLightMediumContrast = Color(0xFFF9F9FF)\nval onSurfaceLightMediumContrast = Color(0xFF191C20)\nval surfaceVariantLightMediumContrast = Color(0xFFE0E2EC)\nval onSurfaceVariantLightMediumContrast = Color(0xFF3F434A)\nval outlineLightMediumContrast = Color(0xFF5B5F67)\nval outlineVariantLightMediumContrast = Color(0xFF777B83)\nval scrimLightMediumContrast = Color(0xFF000000)\nval inverseSurfaceLightMediumContrast = Color(0xFF2E3035)\nval inverseOnSurfaceLightMediumContrast = Color(0xFFF0F0F7)\nval inversePrimaryLightMediumContrast = Color(0xFFA5C8FF)\nval surfaceDimLightMediumContrast = Color(0xFFD9DAE0)\nval surfaceBrightLightMediumContrast = Color(0xFFF9F9FF)\nval surfaceContainerLowestLightMediumContrast = Color(0xFFFFFFFF)\nval surfaceContainerLowLightMediumContrast = Color(0xFFF2F3FA)\nval surfaceContainerLightMediumContrast = Color(0xFFEDEDF4)\nval surfaceContainerHighLightMediumContrast = Color(0xFFE7E8EE)\nval surfaceContainerHighestLightMediumContrast = Color(0xFFE1E2E9)\n\nval primaryLightHighContrast = Color(0xFF002246)\nval onPrimaryLightHighContrast = Color(0xFFFFFFFF)\nval primaryContainerLightHighContrast = Color(0xFF1D4472)\nval onPrimaryContainerLightHighContrast = Color(0xFFFFFFFF)\nval secondaryLightHighContrast = Color(0xFF182332)\nval onSecondaryLightHighContrast = Color(0xFFFFFFFF)\nval secondaryContainerLightHighContrast = Color(0xFF394354)\nval onSecondaryContainerLightHighContrast = Color(0xFFFFFFFF)\nval tertiaryLightHighContrast = Color(0xFF2E1A37)\nval onTertiaryLightHighContrast = Color(0xFFFFFFFF)\nval tertiaryContainerLightHighContrast = Color(0xFF513B59)\nval onTertiaryContainerLightHighContrast = Color(0xFFFFFFFF)\nval errorLightHighContrast = Color(0xFF4E0002)\nval onErrorLightHighContrast = Color(0xFFFFFFFF)\nval errorContainerLightHighContrast = Color(0xFF8C0009)\nval onErrorContainerLightHighContrast = Color(0xFFFFFFFF)\nval backgroundLightHighContrast = Color(0xFFF9F9FF)\nval onBackgroundLightHighContrast = Color(0xFF191C20)\nval surfaceLightHighContrast = Color(0xFFF9F9FF)\nval onSurfaceLightHighContrast = Color(0xFF000000)\nval surfaceVariantLightHighContrast = Color(0xFFE0E2EC)\nval onSurfaceVariantLightHighContrast = Color(0xFF20242B)\nval outlineLightHighContrast = Color(0xFF3F434A)\nval outlineVariantLightHighContrast = Color(0xFF3F434A)\nval scrimLightHighContrast = Color(0xFF000000)\nval inverseSurfaceLightHighContrast = Color(0xFF2E3035)\nval inverseOnSurfaceLightHighContrast = Color(0xFFFFFFFF)\nval inversePrimaryLightHighContrast = Color(0xFFE4ECFF)\nval surfaceDimLightHighContrast = Color(0xFFD9DAE0)\nval surfaceBrightLightHighContrast = Color(0xFFF9F9FF)\nval surfaceContainerLowestLightHighContrast = Color(0xFFFFFFFF)\nval surfaceContainerLowLightHighContrast = Color(0xFFF2F3FA)\nval surfaceContainerLightHighContrast = Color(0xFFEDEDF4)\nval surfaceContainerHighLightHighContrast = Color(0xFFE7E8EE)\nval surfaceContainerHighestLightHighContrast = Color(0xFFE1E2E9)\n\nval primaryDark = Color(0xFFA5C8FF)\nval onPrimaryDark = Color(0xFF00315E)\nval primaryContainerDark = Color(0xFF224876)\nval onPrimaryContainerDark = Color(0xFFD4E3FF)\nval secondaryDark = Color(0xFFBCC7DC)\nval onSecondaryDark = Color(0xFF263141)\nval secondaryContainerDark = Color(0xFF3D4758)\nval onSecondaryContainerDark = Color(0xFFD8E3F8)\nval tertiaryDark = Color(0xFFDABDE2)\nval onTertiaryDark = Color(0xFF3D2946)\nval tertiaryContainerDark = Color(0xFF553F5D)\nval onTertiaryContainerDark = Color(0xFFF7D8FF)\nval errorDark = Color(0xFFFFB4AB)\nval onErrorDark = Color(0xFF690005)\nval errorContainerDark = Color(0xFF93000A)\nval onErrorContainerDark = Color(0xFFFFDAD6)\nval backgroundDark = Color(0xFF111318)\nval onBackgroundDark = Color(0xFFE1E2E9)\nval surfaceDark = Color(0xFF111318)\nval onSurfaceDark = Color(0xFFE1E2E9)\nval surfaceVariantDark = Color(0xFF43474E)\nval onSurfaceVariantDark = Color(0xFFC3C6CF)\nval outlineDark = Color(0xFF8D9199)\nval outlineVariantDark = Color(0xFF43474E)\nval scrimDark = Color(0xFF000000)\nval inverseSurfaceDark = Color(0xFFE1E2E9)\nval inverseOnSurfaceDark = Color(0xFF2E3035)\nval inversePrimaryDark = Color(0xFF3C6090)\nval surfaceDimDark = Color(0xFF111318)\nval surfaceBrightDark = Color(0xFF37393E)\nval surfaceContainerLowestDark = Color(0xFF0C0E13)\nval surfaceContainerLowDark = Color(0xFF191C20)\nval surfaceContainerDark = Color(0xFF1D2024)\nval surfaceContainerHighDark = Color(0xFF282A2F)\nval surfaceContainerHighestDark = Color(0xFF32353A)\n\nval primaryDarkMediumContrast = Color(0xFFACCCFF)\nval onPrimaryDarkMediumContrast = Color(0xFF001631)\nval primaryContainerDarkMediumContrast = Color(0xFF7092C5)\nval onPrimaryContainerDarkMediumContrast = Color(0xFF000000)\nval secondaryDarkMediumContrast = Color(0xFFC1CBE0)\nval onSecondaryDarkMediumContrast = Color(0xFF0C1726)\nval secondaryContainerDarkMediumContrast = Color(0xFF8791A4)\nval onSecondaryContainerDarkMediumContrast = Color(0xFF000000)\nval tertiaryDarkMediumContrast = Color(0xFFDEC1E7)\nval onTertiaryDarkMediumContrast = Color(0xFF210E2A)\nval tertiaryContainerDarkMediumContrast = Color(0xFFA288AB)\nval onTertiaryContainerDarkMediumContrast = Color(0xFF000000)\nval errorDarkMediumContrast = Color(0xFFFFBAB1)\nval onErrorDarkMediumContrast = Color(0xFF370001)\nval errorContainerDarkMediumContrast = Color(0xFFFF5449)\nval onErrorContainerDarkMediumContrast = Color(0xFF000000)\nval backgroundDarkMediumContrast = Color(0xFF111318)\nval onBackgroundDarkMediumContrast = Color(0xFFE1E2E9)\nval surfaceDarkMediumContrast = Color(0xFF111318)\nval onSurfaceDarkMediumContrast = Color(0xFFFBFAFF)\nval surfaceVariantDarkMediumContrast = Color(0xFF43474E)\nval onSurfaceVariantDarkMediumContrast = Color(0xFFC8CAD4)\nval outlineDarkMediumContrast = Color(0xFFA0A3AB)\nval outlineVariantDarkMediumContrast = Color(0xFF80838B)\nval scrimDarkMediumContrast = Color(0xFF000000)\nval inverseSurfaceDarkMediumContrast = Color(0xFFE1E2E9)\nval inverseOnSurfaceDarkMediumContrast = Color(0xFF282A2F)\nval inversePrimaryDarkMediumContrast = Color(0xFF234977)\nval surfaceDimDarkMediumContrast = Color(0xFF111318)\nval surfaceBrightDarkMediumContrast = Color(0xFF37393E)\nval surfaceContainerLowestDarkMediumContrast = Color(0xFF0C0E13)\nval surfaceContainerLowDarkMediumContrast = Color(0xFF191C20)\nval surfaceContainerDarkMediumContrast = Color(0xFF1D2024)\nval surfaceContainerHighDarkMediumContrast = Color(0xFF282A2F)\nval surfaceContainerHighestDarkMediumContrast = Color(0xFF32353A)\n\nval primaryDarkHighContrast = Color(0xFFFBFAFF)\nval onPrimaryDarkHighContrast = Color(0xFF000000)\nval primaryContainerDarkHighContrast = Color(0xFFACCCFF)\nval onPrimaryContainerDarkHighContrast = Color(0xFF000000)\nval secondaryDarkHighContrast = Color(0xFFFBFAFF)\nval onSecondaryDarkHighContrast = Color(0xFF000000)\nval secondaryContainerDarkHighContrast = Color(0xFFC1CBE0)\nval onSecondaryContainerDarkHighContrast = Color(0xFF000000)\nval tertiaryDarkHighContrast = Color(0xFFFFF9FB)\nval onTertiaryDarkHighContrast = Color(0xFF000000)\nval tertiaryContainerDarkHighContrast = Color(0xFFDEC1E7)\nval onTertiaryContainerDarkHighContrast = Color(0xFF000000)\nval errorDarkHighContrast = Color(0xFFFFF9F9)\nval onErrorDarkHighContrast = Color(0xFF000000)\nval errorContainerDarkHighContrast = Color(0xFFFFBAB1)\nval onErrorContainerDarkHighContrast = Color(0xFF000000)\nval backgroundDarkHighContrast = Color(0xFF111318)\nval onBackgroundDarkHighContrast = Color(0xFFE1E2E9)\nval surfaceDarkHighContrast = Color(0xFF111318)\nval onSurfaceDarkHighContrast = Color(0xFFFFFFFF)\nval surfaceVariantDarkHighContrast = Color(0xFF43474E)\nval onSurfaceVariantDarkHighContrast = Color(0xFFFBFAFF)\nval outlineDarkHighContrast = Color(0xFFC8CAD4)\nval outlineVariantDarkHighContrast = Color(0xFFC8CAD4)\nval scrimDarkHighContrast = Color(0xFF000000)\nval inverseSurfaceDarkHighContrast = Color(0xFFE1E2E9)\nval inverseOnSurfaceDarkHighContrast = Color(0xFF000000)\nval inversePrimaryDarkHighContrast = Color(0xFF002A53)\nval surfaceDimDarkHighContrast = Color(0xFF111318)\nval surfaceBrightDarkHighContrast = Color(0xFF37393E)\nval surfaceContainerLowestDarkHighContrast = Color(0xFF0C0E13)\nval surfaceContainerLowDarkHighContrast = Color(0xFF191C20)\nval surfaceContainerDarkHighContrast = Color(0xFF1D2024)\nval surfaceContainerHighDarkHighContrast = Color(0xFF282A2F)\nval surfaceContainerHighestDarkHighContrast = Color(0xFF32353A)\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/theme/ElevationTokens.kt",
    "content": "package com.shicheeng.copymanga.ui.theme\n\nimport androidx.compose.ui.unit.dp\n\nobject ElevationTokens {\n    val Level0 = 0.0.dp\n    val Level1 = 1.0.dp\n    val Level2 = 3.0.dp\n    val Level3 = 6.0.dp\n    val Level4 = 8.0.dp\n    val Level5 = 12.0.dp\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/theme/Theme.kt",
    "content": "package com.shicheeng.copymanga.ui.theme\n\nimport android.app.Activity\nimport android.graphics.Color\nimport android.os.Build\nimport androidx.compose.foundation.isSystemInDarkTheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.darkColorScheme\nimport androidx.compose.material3.dynamicDarkColorScheme\nimport androidx.compose.material3.dynamicLightColorScheme\nimport androidx.compose.material3.lightColorScheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.platform.LocalView\nimport androidx.core.view.WindowCompat\nimport com.google.accompanist.themeadapter.material3.createMdc3Theme\n\nprivate val lightScheme = lightColorScheme(\n    primary = primaryLight,\n    onPrimary = onPrimaryLight,\n    primaryContainer = primaryContainerLight,\n    onPrimaryContainer = onPrimaryContainerLight,\n    secondary = secondaryLight,\n    onSecondary = onSecondaryLight,\n    secondaryContainer = secondaryContainerLight,\n    onSecondaryContainer = onSecondaryContainerLight,\n    tertiary = tertiaryLight,\n    onTertiary = onTertiaryLight,\n    tertiaryContainer = tertiaryContainerLight,\n    onTertiaryContainer = onTertiaryContainerLight,\n    error = errorLight,\n    onError = onErrorLight,\n    errorContainer = errorContainerLight,\n    onErrorContainer = onErrorContainerLight,\n    background = backgroundLight,\n    onBackground = onBackgroundLight,\n    surface = surfaceLight,\n    onSurface = onSurfaceLight,\n    surfaceVariant = surfaceVariantLight,\n    onSurfaceVariant = onSurfaceVariantLight,\n    outline = outlineLight,\n    outlineVariant = outlineVariantLight,\n    scrim = scrimLight,\n    inverseSurface = inverseSurfaceLight,\n    inverseOnSurface = inverseOnSurfaceLight,\n    inversePrimary = inversePrimaryLight,\n    surfaceDim = surfaceDimLight,\n    surfaceBright = surfaceBrightLight,\n    surfaceContainerLowest = surfaceContainerLowestLight,\n    surfaceContainerLow = surfaceContainerLowLight,\n    surfaceContainer = surfaceContainerLight,\n    surfaceContainerHigh = surfaceContainerHighLight,\n    surfaceContainerHighest = surfaceContainerHighestLight,\n)\n\nprivate val darkScheme = darkColorScheme(\n    primary = primaryDark,\n    onPrimary = onPrimaryDark,\n    primaryContainer = primaryContainerDark,\n    onPrimaryContainer = onPrimaryContainerDark,\n    secondary = secondaryDark,\n    onSecondary = onSecondaryDark,\n    secondaryContainer = secondaryContainerDark,\n    onSecondaryContainer = onSecondaryContainerDark,\n    tertiary = tertiaryDark,\n    onTertiary = onTertiaryDark,\n    tertiaryContainer = tertiaryContainerDark,\n    onTertiaryContainer = onTertiaryContainerDark,\n    error = errorDark,\n    onError = onErrorDark,\n    errorContainer = errorContainerDark,\n    onErrorContainer = onErrorContainerDark,\n    background = backgroundDark,\n    onBackground = onBackgroundDark,\n    surface = surfaceDark,\n    onSurface = onSurfaceDark,\n    surfaceVariant = surfaceVariantDark,\n    onSurfaceVariant = onSurfaceVariantDark,\n    outline = outlineDark,\n    outlineVariant = outlineVariantDark,\n    scrim = scrimDark,\n    inverseSurface = inverseSurfaceDark,\n    inverseOnSurface = inverseOnSurfaceDark,\n    inversePrimary = inversePrimaryDark,\n    surfaceDim = surfaceDimDark,\n    surfaceBright = surfaceBrightDark,\n    surfaceContainerLowest = surfaceContainerLowestDark,\n    surfaceContainerLow = surfaceContainerLowDark,\n    surfaceContainer = surfaceContainerDark,\n    surfaceContainerHigh = surfaceContainerHighDark,\n    surfaceContainerHighest = surfaceContainerHighestDark,\n)\n\n\n/**\n * 拷贝漫画的主题\n */\n@Composable\nfun CopyMangaTheme(\n    dynamicColor: Boolean = true,\n    darkTheme: Boolean = isSystemInDarkTheme(),\n    content: @Composable () -> Unit,\n) {\n\n    val context = LocalContext.current\n    val colorScheme = when {\n        dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {\n            if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)\n        }\n\n        darkTheme -> darkScheme\n        else -> lightScheme\n    }\n    val view = LocalView.current\n    if (!view.isInEditMode) {\n        SideEffect {\n            val window = (view.context as Activity).window\n            window.statusBarColor = Color.TRANSPARENT\n            window.navigationBarColor = Color.TRANSPARENT\n            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n                window.isStatusBarContrastEnforced = false\n                window.isNavigationBarContrastEnforced = false\n            }\n            WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme\n            WindowCompat.setDecorFitsSystemWindows(window, false)\n        }\n    }\n\n    MaterialTheme(\n        content = content,\n        colorScheme = colorScheme,\n        typography = typography\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/ui/theme/Typo.kt",
    "content": "package com.shicheeng.copymanga.ui.theme\n\nimport androidx.compose.material3.Typography\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.font.FontStyle\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.unit.sp\n\n\nval MonospaceStyle: TextStyle = TextStyle(\n    fontStyle = FontStyle.Normal,\n    fontWeight = FontWeight.Normal,\n    fontFamily = FontFamily.Monospace,\n    fontSize = 12.sp\n)\n\nval typography = Typography()\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/FileCacheUtils.java",
    "content": "package com.shicheeng.copymanga.util;\n\nimport android.content.Context;\n\nimport java.io.File;\nimport java.math.BigDecimal;\nimport java.math.RoundingMode;\nimport java.util.Objects;\n\npublic class FileCacheUtils {\n\n    /**\n     * 获取缓存大小\n     *\n     * @param context 上下文\n     * @return 大小\n     */\n    public static String getCacheSize(Context context) {\n        return getFormatSize(getFolderSize(context.getCacheDir()) + getFolderSize(context.getExternalCacheDir()));\n    }\n\n\n    /**\n     * 获取文件大小\n     */\n    public static long getFolderSize(File file) {\n        long size = 0;\n        try {\n            File[] fileList = file.listFiles();\n            for (int i = 0; i < Objects.requireNonNull(fileList).length; i++) {\n                // 如果下面还有文件\n                if (fileList[i].isDirectory()) {\n                    size = size + getFolderSize(fileList[i]);\n                } else {\n                    size = size + fileList[i].length();\n                }\n            }\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return size;\n    }\n\n\n    /**\n     * 格式化文件大小单位\n     *\n     * @param size 大小\n     * @return 格式化\n     */\n    public static String getFormatSize(double size) {\n        double kiloByte = size / 1024;\n        if (kiloByte < 1) {\n            return size + \"Byte\";\n        }\n\n        double megaByte = kiloByte / 1024;\n        if (megaByte < 1) {\n            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));\n            return result1.setScale(2, RoundingMode.HALF_UP)\n                    .toPlainString() + \"KB\";\n        }\n\n        double gigaByte = megaByte / 1024;\n        if (gigaByte < 1) {\n            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));\n            return result2.setScale(2, RoundingMode.HALF_UP)\n                    .toPlainString() + \"MB\";\n        }\n\n        double teraBytes = gigaByte / 1024;\n        if (teraBytes < 1) {\n            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));\n            return result3.setScale(2, RoundingMode.HALF_UP)\n                    .toPlainString() + \"GB\";\n        }\n        BigDecimal result4 = new BigDecimal(teraBytes);\n        return result4.setScale(2, RoundingMode.HALF_UP).toPlainString()\n                + \"TB\";\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/FirstSnapHelper.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport android.content.Context\nimport android.util.DisplayMetrics\nimport android.view.View\nimport android.view.animation.DecelerateInterpolator\nimport android.widget.Scroller\nimport androidx.recyclerview.widget.LinearSmoothScroller\nimport androidx.recyclerview.widget.LinearSnapHelper\nimport androidx.recyclerview.widget.OrientationHelper\nimport androidx.recyclerview.widget.RecyclerView\n\nclass FirstSnapHelper : LinearSnapHelper() {\n\n    companion object {\n        private const val MILLISECONDS_PER_INCH = 100f\n        private const val MAX_SCROLL_ON_FLING_DURATION_MS = 1000\n    }\n\n\n    private var context: Context? = null\n    private var helper: OrientationHelper? = null\n    private var scroller: Scroller? = null\n    private var maxScrollDistance: Int = 0\n\n    override fun findSnapView(layoutManager: RecyclerView.LayoutManager?): View? {\n        return firstFirstView(layoutManager, helper(layoutManager))\n    }\n\n    override fun attachToRecyclerView(recyclerView: RecyclerView?) {\n        if (recyclerView != null) {\n            context = recyclerView.context\n            scroller = Scroller(context, DecelerateInterpolator())\n        } else {\n            scroller = null\n            context = null\n        }\n        super.attachToRecyclerView(recyclerView)\n    }\n\n\n    override fun calculateDistanceToFinalSnap(\n        layoutManager: RecyclerView.LayoutManager,\n        targetView: View,\n    ): IntArray {\n        val out = IntArray(2)\n        out[0] = distanceToStart(targetView, helper(layoutManager))\n        return out\n    }\n\n    override fun calculateScrollDistance(velocityX: Int, velocityY: Int): IntArray {\n        val out = IntArray(2)\n        val helper = helper ?: return out\n\n        if (maxScrollDistance == 0) {\n            maxScrollDistance = (helper.endAfterPadding - helper.startAfterPadding) / 2\n        }\n\n        scroller?.fling(0, 0, velocityX, velocityY, -maxScrollDistance, maxScrollDistance, 0, 0)\n        out[0] = scroller?.finalX ?: 0\n        out[1] = scroller?.finalY ?: 0\n        return out\n    }\n\n    override fun createScroller(layoutManager: RecyclerView.LayoutManager): RecyclerView.SmoothScroller? {\n\n        if (layoutManager !is RecyclerView.SmoothScroller.ScrollVectorProvider)\n            return super.createScroller(layoutManager)\n        val context = context ?: return null\n        return object : LinearSmoothScroller(context) {\n            override fun onTargetFound(\n                targetView: View,\n                state: RecyclerView.State,\n                action: Action,\n            ) {\n                val snapDistance = calculateDistanceToFinalSnap(layoutManager, targetView)\n                val dx = snapDistance[0]\n                val dy = snapDistance[1]\n                val dt = calculateTimeForDeceleration(Math.abs(dx))\n                val time = 1.coerceAtLeast(MAX_SCROLL_ON_FLING_DURATION_MS.coerceAtMost(dt))\n                action.update(dx, dy, time, mDecelerateInterpolator)\n            }\n\n            override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float =\n                MILLISECONDS_PER_INCH / displayMetrics.densityDpi\n        }\n    }\n\n    private fun distanceToStart(targetView: View, helper: OrientationHelper): Int {\n        val childStart = helper.getDecoratedStart(targetView)\n        val containerStart = helper.startAfterPadding\n        return childStart - containerStart\n    }\n\n    private fun firstFirstView(\n        layoutManager: RecyclerView.LayoutManager?,\n        helper: OrientationHelper,\n    ): View? {\n        if (layoutManager == null) return null\n        val childCount = layoutManager.childCount\n        if (childCount == 0) return null\n        var absClosest = Int.MAX_VALUE\n        var closestView: View? = null\n        val start = helper.startAfterPadding\n        for (i in 0 until childCount) {\n            val child = layoutManager.getChildAt(i)\n            val childStart = helper.getDecoratedStart(child)\n            val absDistanceToStart = Math.abs(childStart - start)\n            if (absDistanceToStart < absClosest) {\n                absClosest = absDistanceToStart\n                closestView = child\n            }\n        }\n        return closestView\n    }\n\n\n    private fun helper(layoutManager: RecyclerView.LayoutManager?): OrientationHelper {\n        if (helper == null) {\n            helper = OrientationHelper.createHorizontalHelper(layoutManager)\n        }\n        return helper!!\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/FunctionUtils.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport android.content.Context\nimport android.content.Intent\nimport android.graphics.Rect\nimport android.graphics.drawable.Drawable\nimport android.net.Uri\nimport android.provider.Settings\nimport android.util.TypedValue\nimport android.view.View\nimport androidx.activity.ComponentActivity\nimport androidx.activity.viewModels\nimport androidx.annotation.ColorInt\nimport androidx.annotation.MainThread\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.combinedClickable\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.ExperimentalLayoutApi\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.imePadding\nimport androidx.compose.foundation.layout.isImeVisible\nimport androidx.compose.foundation.layout.navigationBars\nimport androidx.compose.foundation.layout.navigationBarsPadding\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.fragment.app.Fragment\nimport androidx.fragment.app.viewModels\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.LiveData\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.ViewModelProvider\nimport androidx.lifecycle.coroutineScope\nimport androidx.lifecycle.repeatOnLifecycle\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.google.android.material.shape.MaterialShapeDrawable\nimport com.google.gson.JsonArray\nimport com.google.gson.JsonElement\nimport com.google.gson.JsonObject\nimport com.google.gson.JsonParser\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\nimport okio.Closeable\nimport java.text.SimpleDateFormat\nimport java.time.Instant\nimport java.time.ZoneId\nimport java.time.format.DateTimeFormatter\nimport java.time.format.FormatStyle\nimport java.util.*\nimport kotlin.coroutines.CoroutineContext\n\n/**\n * 将[JsonArray]转化为[String]对象。\n */\nfun JsonArray.authorNameReformation(): String =\n    if (size() == 1) get(0).asJsonObject[\"name\"].asString else get(0).asJsonObject[\"name\"].asString + \" 等\"\n\n\n@MainThread\ninline fun <T> Flow<T>.collectRepeatLifecycle(\n    lifecycleOwner: LifecycleOwner,\n    crossinline collected: (T) -> Unit,\n) {\n    lifecycleOwner.lifecycle.coroutineScope.launch {\n        lifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.CREATED) {\n            collectLatest { collected(it) }\n        }\n    }\n}\n\n@MainThread\ninline fun <reified VM : ViewModel> Fragment.assistedViewModels(\n    noinline factoryProducer: () -> VM,\n): Lazy<VM> = viewModels {\n    object : ViewModelProvider.Factory {\n        override fun <T : ViewModel> create(modelClass: Class<T>): T {\n            return requireNotNull(modelClass.cast(factoryProducer.invoke()))\n        }\n    }\n}\n\ninfix fun Context.openUrl(string: String) {\n    startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(string)))\n}\n\n@MainThread\ninline fun <reified VM : ViewModel> ComponentActivity.assistedViewModels(\n    noinline factoryProducer: () -> VM,\n): Lazy<VM> = viewModels {\n    object : ViewModelProvider.Factory {\n        override fun <T : ViewModel> create(modelClass: Class<T>): T {\n            return requireNotNull(modelClass.cast(factoryProducer.invoke()))\n        }\n    }\n}\n\n/**\n * 复制一份[PaddingValues]。区别于[PaddingValues.copyComposable],该函数需要传递[LayoutDirection]。\n */\nfun PaddingValues.copy(\n    layoutDirection: LayoutDirection,\n    top: Dp = this.calculateTopPadding(),\n    bottom: Dp = this.calculateBottomPadding(),\n    start: Dp = this.calculateStartPadding(layoutDirection),\n    end: Dp = this.calculateEndPadding(layoutDirection),\n): PaddingValues {\n    return PaddingValues(start = start, top = top, end = end, bottom = bottom)\n}\n\n/**\n * 复制一份[PaddingValues]。区别于[PaddingValues.copy],该函数**不**需要传递[LayoutDirection]。\n * 并且该函数是[Composable]函数。\n */\n@Composable\nfun PaddingValues.copyComposable(\n    layoutDirection: LayoutDirection = LocalLayoutDirection.current,\n    top: Dp = this.calculateTopPadding(),\n    bottom: Dp = this.calculateBottomPadding(),\n    start: Dp = this.calculateStartPadding(layoutDirection),\n    end: Dp = this.calculateEndPadding(layoutDirection),\n): PaddingValues {\n    return PaddingValues(start = start, top = top, end = end, bottom = bottom)\n}\n\n/**\n *\n * Copy from [tachiyomi](https://github.com/tachiyomiorg/tachiyomi/blob/820ed6a46880af1e9390706dc9915f3c7d385c60/app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt)\n *\n */\n@ColorInt\nfun Context.getThemeColor(attr: Int): Int {\n    val tv = TypedValue()\n    return if (this.theme.resolveAttribute(attr, tv, true)) {\n        if (tv.resourceId != 0) {\n            getColor(tv.resourceId)\n        } else {\n            tv.data\n        }\n    } else {\n        0\n    }\n}\n\n/**\n * Returns a deep copy of the provided [Drawable]\n *\n * Copy from tachiyomi\n */\ninline fun <reified T : Drawable> T.copy(context: Context): T? {\n    return (constantState?.newDrawable()?.mutate() as? T).apply {\n        if (this is MaterialShapeDrawable) {\n            initializeElevationOverlay(context)\n        }\n    }\n}\n\n/**\n * Refer from Kotatsu\n *\n * 新旧交替检测\n */\n@Deprecated(\"不再使用LiveData\")\nfun <T> LiveData<T>.observeWithPrevious(owner: LifecycleOwner, observer: BufferedObserver<T>) {\n    var previous: T? = null\n    this.observe(owner) {\n        observer.onChanged(it, previous)\n        previous = it\n    }\n}\n\nfun String.parserToJson(): JsonElement = JsonParser.parseString(this)\n\n/**\n * 没有波纹动画的点击监听\n */\n@OptIn(ExperimentalFoundationApi::class)\nfun Modifier.click(onClick: () -> Unit) = composed {\n    combinedClickable(\n        onClick = onClick,\n        onLongClick = null,\n        interactionSource = remember { MutableInteractionSource() },\n        indication = null\n    )\n}\n\nfun RecyclerView.findCurrentPagePosition(): Int {\n    val x = width / 2f\n    val y = height / 2f\n    val view = findChildViewUnder(x, y) ?: return RecyclerView.NO_POSITION\n    return getChildAdapterPosition(view)\n}\n\nfun String.transformToUUIDMayNull(): UUID? {\n    return try {\n        UUID.fromString(this)\n    } catch (e: Exception) {\n        e.printStackTrace()\n        null\n    }\n}\n\nfun String?.transformToUUIDMayNullSafety(): UUID? {\n    return try {\n        UUID.fromString(this)\n    } catch (e: Exception) {\n        e.printStackTrace()\n        null\n    }\n}\n\nval Exception.messageNoNull: String\n    get() {\n        return if (message == null || message.isNullOrBlank() || message.isNullOrEmpty()) {\n            \"ERROR BUT NO MESSAGE\"\n        } else {\n            message as String\n        }\n    }\n\nfun RecyclerView.setFirstVisibleItemPositionSmooth(position: Int, smooth: Boolean) {\n    if (position != RecyclerView.NO_POSITION) {\n        if (smooth) {\n            smoothScrollToPosition(position)\n        } else {\n            scrollToPosition(position)\n        }\n    }\n}\n\n/**\n * Return recycler first item position\n */\nvar RecyclerView.firstVisibleItemPosition: Int\n    get() = (layoutManager as? LinearLayoutManager)?.findFirstVisibleItemPosition()\n        ?: RecyclerView.NO_POSITION\n    set(value) {\n        if (value != RecyclerView.NO_POSITION) {\n            (layoutManager as? LinearLayoutManager)?.scrollToPositionWithOffset(value, 0)\n        }\n    }\n\nfun String.parserAsJson(): JsonElement = JsonParser.parseString(this)\n\nfun JsonElement.transformToJsonObjectSafety(): JsonObject? = try {\n    asJsonObject\n} catch (e: IllegalStateException) {\n    null\n}\n\nfun JsonObject.getOrNull(member: String): JsonElement? {\n    return if (has(member)) get(member) else null\n}\n\nfun String?.nullWillBe(newString: () -> String): String {\n    return this ?: return newString()\n}\n\n/**\n * 将大数字转化为可读性数字。没有i18n。\n */\nfun Long.formNumberToRead(): String {\n\n    return when {\n        this >= 1000000000 -> {\n            String.format(\"%.2f 亿\", this / 1000000000.0)\n        }\n\n        this >= 10000000 -> {\n            String.format(\"%.2f 千万\", this / 1000000.0)\n        }\n\n        this >= 10000 -> {\n            String.format(\"%.2f 万\", this / 10000.0)\n        }\n\n        this >= 1000 -> {\n            String.format(\"%.2f 千\", this / 1000.0)\n        }\n\n        else -> this.toString()\n    }\n\n}\n\n/**\n * Time convert\n */\nfun String.timeStampConvert(): String {\n    val sfd = SimpleDateFormat(\"yyyy/MM/dd HH:mm\", Locale.ROOT)\n    val timeStamp = Instant.parse(this).toEpochMilli()\n    return sfd.format(timeStamp)\n}\n\n/**\n * Copy from Kotatsu\n */\nfun View.hasGlobalPoint(x: Int, y: Int): Boolean {\n    if (visibility != View.VISIBLE) {\n        return false\n    }\n    val rect = Rect()\n    getGlobalVisibleRect(rect)\n    return rect.contains(x, y)\n}\n\nsuspend fun <T : Closeable?, R> T.useWithContext(\n    coroutineContext: CoroutineContext,\n    block: (t: T) -> R,\n) = withContext(coroutineContext) {\n    use(block = block)\n}\n\nfun <T : JsonElement> JsonObject.add(property: String, jsonElement: () -> T) {\n    add(property, jsonElement())\n}\n\nfun <T> List<T>.toJsonArray(\n    headerProperty: String,\n    header: (T) -> String,\n    valuesProperty: String,\n    values: (T) -> String,\n): JsonArray {\n    val jsonArray = JsonArray()\n    forEach {\n        val jsonObjects = JsonObject().apply {\n            addProperty(headerProperty, header(it))\n            addProperty(valuesProperty, values(it))\n        }\n        jsonArray.add(jsonObjects)\n    }\n    return jsonArray\n}\n\n/**\n * Format long to Time\n *\n * The format -> 2023/2/22 12:15\n */\n@Deprecated(\"使用更加安全的方法\", replaceWith = ReplaceWith(\"toTimeReadableCompat()\"))\nfun Long.toTimeReadable(): String {\n    val date = Date(this)\n    val sfd = SimpleDateFormat(\"yyyy/MM/dd HH:mm\", Locale.ROOT)\n    return sfd.format(date)\n}\n\nfun Long.convertToTimeGroup(): String {\n    val sfd = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)\n    return sfd.format(Instant.ofEpochMilli(this).atZone(ZoneId.systemDefault()))\n}\n\nfun Long.convertToOnlyTime(): String {\n    val sfd = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)\n    return sfd.format(Instant.ofEpochMilli(this).atZone(ZoneId.systemDefault()))\n}\n\nfun Long.toTimeReadableCompat(): String {\n    val sfd = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)\n    return sfd.format(Instant.ofEpochMilli(this).atZone(ZoneId.systemDefault()))\n}\n\n\n/**\n * Copy from Kotatsu\n */\nfun <T> Collection<T>.asArrayList(): ArrayList<T> = if (this is ArrayList<*>) {\n    this as ArrayList<T>\n} else {\n    ArrayList(this)\n}\n\nfun interface BufferedObserver<T> {\n    fun onChanged(t: T, prev: T?)\n}\n\nval Context.animatorDurationScale: Float\n    get() = Settings.Global.getFloat(\n        this.contentResolver,\n        Settings.Global.ANIMATOR_DURATION_SCALE,\n        1f\n    )\n\n// TODO: 完美的Insets\n@OptIn(ExperimentalLayoutApi::class)\nfun Modifier.withImeNavigationBarPadding() = composed {\n    if (WindowInsets.isImeVisible) {\n        Modifier\n            .imePadding()\n            .padding(\n                bottom = WindowInsets.navigationBars\n                    .asPaddingValues()\n                    .calculateBottomPadding() + 16.dp\n            )\n    } else {\n        Modifier.navigationBarsPadding()\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/GestureHelper.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport android.content.Context\nimport android.view.GestureDetector\nimport android.view.MotionEvent\nimport kotlin.math.roundToInt\n\nclass GestureHelper(context: Context, private val listener: GestureListener) :\n    GestureDetector.SimpleOnGestureListener() {\n\n    private val detector = GestureDetector(context, this)\n    private val width = context.resources.displayMetrics.widthPixels\n    private val height = context.resources.displayMetrics.heightPixels\n    private var isDispatching = false\n\n    init {\n        detector.setIsLongpressEnabled(true)\n        detector.setOnDoubleTapListener(this)\n    }\n\n    fun dispatchTouchEvent(event: MotionEvent) {\n        if (event.actionMasked == MotionEvent.ACTION_DOWN) {\n            isDispatching = listener.onProcessTouch(event.rawX.toInt(), event.rawY.toInt())\n        }\n        detector.onTouchEvent(event)\n    }\n\n    override fun onSingleTapConfirmed(e: MotionEvent): Boolean {\n        if (!isDispatching) {\n            return true\n        }\n        val xIndex = (e.rawX * 2f / width).roundToInt()\n        val yIndex = (e.rawY * 2f / height).roundToInt()\n        listener.onTouch(\n            when (xIndex) {\n                0 -> AREA_LEFT\n                1 -> {\n                    when (yIndex) {\n                        0 -> AREA_TOP\n                        1 -> AREA_CENTER\n                        2 -> AREA_BOTTOM\n                        else -> return false\n                    }\n                }\n                2 -> AREA_RIGHT\n                else -> return false\n            },\n        )\n        return true\n    }\n\n    companion object {\n        const val AREA_CENTER = 1\n        const val AREA_LEFT = 2\n        const val AREA_RIGHT = 3\n        const val AREA_TOP = 4\n        const val AREA_BOTTOM = 5\n    }\n\n    interface GestureListener {\n        fun onTouch(area: Int)\n\n        fun onProcessTouch(rawX: Int, rawY: Int): Boolean\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/JsonObjectExtra.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport com.google.gson.JsonElement\nimport com.google.gson.JsonObject\nimport com.google.gson.JsonParser\n\nval String.asJsonElementOrNull: JsonElement?\n    get() {\n        return if (this.isEmpty() || this.isNotBlank()) {\n            null\n        } else {\n            val element = JsonParser.parseString(this)\n            if (element.isJsonNull) null\n            else element\n        }\n    }\n\nval JsonElement.asStringOrNull: String?\n    get() {\n        return if (this.isJsonNull) {\n            null\n        } else {\n            this.asString\n        }\n    }\n\nfun JsonObject.getOr(member: String, other: () -> JsonElement): JsonElement {\n    return if (this.has(member) && !this.get(member).isJsonNull) {\n        this.get(member)\n    } else {\n        other()\n    }\n}\n\nfun JsonObject.orEmptyJsonObject(): JsonObject = if (this.isEmpty) JsonObject() else this"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/KeyWordSwap.java",
    "content": "package com.shicheeng.copymanga.util;\n\npublic class KeyWordSwap {\n    public static final String DAY_RANK = \"day\";\n    public static final String WEEK_RANK = \"week\";\n    public static final String MONTH_RANK = \"month\";\n    public static final String TOTAL_RANK = \"total\";\n    public static final String FAKE_USER_AGENT = \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36\";\n    public static final String USER_AGENT_WORD = \"User-Agent\";\n    public static final String PATH_WORD_TYPE = \"path_word\";\n    public static final String MANGA_TITLE_TYPE = \"manga_title\";\n    public static final String CHAPTER_TYPE = \"chapter\";\n    public static final String CHAPTER_TYPE_FOR_BUNDLE = \"chapter_type_in_bundle\";\n    public static final String SAVED_LOCAL_CHAPTER_NAME = \"DownloadChapters.json\";\n    public static final String LOCAL_SAVABLE_INDEX_JSON = \"index.json\";\n    public static final int HANDLER_INFO_1_WHAT = 0x01;\n    public static final String FLAG_ = \"FLAG\";\n    public static final String NON_JSON = \"NON_JSON\";\n    public static final String EXTRA_CANCEL_ID = \"INTENT_KEY_CANCEL\";\n    public static final String RECEIVER_CANCEL = \"RECEIVER_CANCEL\";\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/OkhttpHelper.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport androidx.compose.runtime.Immutable\nimport com.shicheeng.copymanga.error.ContinuationCallCallback\nimport kotlinx.coroutines.suspendCancellableCoroutine\nimport okhttp3.Call\nimport okhttp3.Response\n\n/**\n * Copy from [Kotatsu](https://github.com/KotatsuApp/Kotatsu).\n */\nsuspend fun Call.await(): Response = suspendCancellableCoroutine {\n    val callback = ContinuationCallCallback(this, it)\n    enqueue(callback)\n    it.invokeOnCancellation(callback)\n}\n\nsealed class UIState<out T> {\n    @Immutable\n    data class Success<T>(val content: T) : UIState<T>()\n\n    @Immutable\n    data class Error<E : Exception>(val errorMessage: E) : UIState<Nothing>()\n\n    @Immutable\n    object Loading : UIState<Nothing>()\n}\n\nsealed class LoginState<out T> {\n    @Immutable\n    data class Success<T>(val content: T) : LoginState<T>()\n\n    @Immutable\n    data class Error<E : Exception>(val errorMessage: E) : LoginState<Nothing>()\n\n    @Immutable\n    object Loading : LoginState<Nothing>()\n\n    @Immutable\n    object NoStatus : LoginState<Nothing>()\n}\n\nsealed class SendUIState<T : Any> {\n    @Immutable\n    data class Success<T : Any>(val data: T) : SendUIState<T>()\n\n    @Immutable\n    data class Error<T : Any>(val errorMessage: Throwable) : SendUIState<T>()\n\n    @Immutable\n    object Loading : SendUIState<Nothing>()\n\n    @Immutable\n    object Idle : SendUIState<Nothing>()\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/ProcessLifecycle.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport androidx.lifecycle.LifecycleCoroutineScope\nimport androidx.lifecycle.ProcessLifecycleOwner\nimport androidx.lifecycle.lifecycleScope\n\nval processLifecycleScope: LifecycleCoroutineScope\n    inline get() = ProcessLifecycleOwner.get().lifecycleScope"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/ReaderSliderAttach.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport com.google.android.material.slider.Slider\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.viewmodel.ReaderViewModel\n\nprivate const val FRAGMENT_MAIN = \"Main\"\n\nclass ReaderSliderAttach(\n    private val callBack: PageSelectPosition,\n    private val viewModel: ReaderViewModel,\n) : Slider.OnChangeListener {\n\n    override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) {\n        if (fromUser) {\n            this moveTo value.toInt()\n        }\n    }\n\n    fun attach(slider: Slider) {\n        slider.addOnChangeListener(this)\n    }\n\n    private infix fun moveTo(position: Int) {\n        val pages = viewModel.currentChapterPage\n        val page = pages[position]\n        callBack.onPositionCallBack(page)\n    }\n\n}\n\ninterface PageSelectPosition {\n    fun onPositionCallBack(page: MangaReaderPage)\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/RetainedLifecycleCoroutineScope.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport dagger.hilt.android.lifecycle.RetainedLifecycle\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.SupervisorJob\nimport kotlinx.coroutines.cancel\nimport kotlin.coroutines.CoroutineContext\n\nclass RetainedLifecycleCoroutineScope(\n\tval lifecycle: RetainedLifecycle,\n) : CoroutineScope, RetainedLifecycle.OnClearedListener {\n\n\toverride val coroutineContext: CoroutineContext = SupervisorJob() + Dispatchers.Main.immediate\n\n\tinit {\n\t\tlifecycle.addOnClearedListener(this)\n\t}\n\n\toverride fun onCleared() {\n\t\tcoroutineContext.cancel()\n\t}\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/RetryableFlow.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.FlowPreview\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.flatMapConcat\nimport kotlinx.coroutines.flow.onEach\n\n@OptIn(ExperimentalCoroutinesApi::class)\n@FlowPreview\nfun <T> retryableFlow(retryTrigger: RetryTrigger, flowProvider: () -> Flow<T>) =\n    retryTrigger.retryEvent.filter { it == RetryTrigger.State.RETRYING }\n        .flatMapConcat { flowProvider() }\n        .onEach { retryTrigger.retryEvent.value = RetryTrigger.State.IDLE }\n\n\nclass RetryTrigger {\n    enum class State { RETRYING, IDLE }\n\n    val retryEvent = MutableStateFlow(State.RETRYING)\n    val retryTriggerFlow = retryEvent.asStateFlow()\n\n    fun retry() {\n        retryEvent.value = State.RETRYING\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/RunCatchingExtra.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport kotlinx.coroutines.CancellationException\n\ninline fun <T, R> T.runCatchingCancellable(block: T.() -> R): Result<R> {\n    return try {\n        Result.success(block())\n    } catch (e: InterruptedException) {\n        throw e\n    } catch (e: CancellationException) {\n        throw e\n    } catch (e: Throwable) {\n        Result.failure(e)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/SharedPreferenceExtra.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport android.content.SharedPreferences\nimport kotlinx.coroutines.channels.awaitClose\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.callbackFlow\nimport kotlinx.coroutines.flow.conflate\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.filterNotNull\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.stateIn\n\nfun SharedPreferences.booleanFlow(key: String): Flow<Boolean> {\n    return keyChanger()\n        .filter { !it.isNullOrBlank() && it.isNotEmpty() }\n        .filterNotNull()\n        .filter { it == key }\n        .map {\n            getBoolean(key, false)\n        }\n        .conflate()\n}\n\n/**\n * 返回一个字串符，但是是[Flow]。\n * 注意：如果需要使用[stateIn]方法最好加入初始时。\n *\n * @param key KEY.\n */\nfun SharedPreferences.stringFlow(key: String): Flow<String?> {\n    return keyChanger()\n        .filter { !it.isNullOrBlank() && it.isNotEmpty() }\n        .filterNotNull()\n        .filter { it == key }\n        .map {\n            getString(key, null)\n        }\n        .conflate()\n}\n\nfun SharedPreferences.integerFlow(key: String, def: Int): Flow<Int> {\n    return keyChanger()\n        .filter { !it.isNullOrBlank() && it.isNotEmpty() }\n        .filterNotNull()\n        .filter { it == key }\n        .map {\n            getInt(key, def)\n        }\n        .conflate()\n}\n\nprivate fun SharedPreferences.keyChanger(): Flow<String?> {\n    return callbackFlow {\n        val listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->\n            trySend(key)\n        }\n        registerOnSharedPreferenceChangeListener(listener)\n        awaitClose {\n            unregisterOnSharedPreferenceChangeListener(listener)\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/StateFlowExtra.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleOwner\nimport androidx.lifecycle.lifecycleScope\nimport androidx.lifecycle.repeatOnLifecycle\nimport kotlinx.coroutines.CoroutineStart\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.FlowCollector\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.flow\nimport kotlinx.coroutines.launch\n\nfun <T> Flow<T>.observe(owner: LifecycleOwner, collector: FlowCollector<T>) {\n    val start = if (this is StateFlow) CoroutineStart.UNDISPATCHED else CoroutineStart.DEFAULT\n    owner.lifecycleScope.launch(start = start) {\n        collect(collector)\n    }\n}\n\nfun <T> Flow<T>.observe(\n    owner: LifecycleOwner,\n    minState: Lifecycle.State,\n    collector: FlowCollector<T>,\n) {\n    owner.lifecycleScope.launch {\n        owner.lifecycle.repeatOnLifecycle(minState) {\n            collect(collector)\n        }\n    }\n}\n\nfun <T> Flow<T>.transformPair(): Flow<Pair<T?, T>> = flow {\n    var previous: T? = null\n    collect { thing ->\n        val result = previous to thing\n        previous = thing\n        emit(result)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/ThemeChanger.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport androidx.appcompat.app.AppCompatDelegate\n\nenum class ThemeMode {\n    LIGHT, DARK, SYSTEM;\n}\n\nfun setSystemNightMode(themeMode: ThemeMode) {\n    AppCompatDelegate.setDefaultNightMode(\n        when (themeMode) {\n            ThemeMode.LIGHT -> AppCompatDelegate.MODE_NIGHT_NO\n            ThemeMode.DARK -> AppCompatDelegate.MODE_NIGHT_YES\n            ThemeMode.SYSTEM -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM\n        },\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/Throttler.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport android.os.SystemClock\n\nclass Throttler(\n\tprivate val timeoutMs: Long,\n) {\n\n\tprivate var lastTick = 0L\n\n\tfun throttle(): Boolean {\n\t\tval now = SystemClock.elapsedRealtime()\n\t\treturn if (lastTick + timeoutMs <= now) {\n\t\t\tlastTick = now\n\t\t\ttrue\n\t\t} else {\n\t\t\tfalse\n\t\t}\n\t}\n\n\tfun reset() {\n\t\tlastTick = 0L\n\t}\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/ViewExtra.kt",
    "content": "package com.shicheeng.copymanga.util\n\nimport androidx.viewpager2.widget.ViewPager2\n\ninline fun ViewPager2.onPageChangeCallback(crossinline position: (Int) -> Unit) {\n    registerOnPageChangeCallback(\n        object : ViewPager2.OnPageChangeCallback() {\n\n            override fun onPageSelected(position: Int) {\n                super.onPageSelected(position)\n                position(position)\n            }\n        }\n    )\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/file/FileSequence.kt",
    "content": "package com.shicheeng.copymanga.util.file\n\nimport com.shicheeng.copymanga.util.iterator.CloseableIterator\nimport com.shicheeng.copymanga.util.iterator.MappingIterator\nimport java.io.File\nimport java.nio.file.Files\nimport java.nio.file.Path\n\nclass FileSequence(private val dir: File) : Sequence<File> {\n\n    override fun iterator(): Iterator<File> {\n        val stream = Files.newDirectoryStream(dir.toPath())\n        return CloseableIterator(\n            MappingIterator(stream.iterator(), Path::toFile),\n            stream\n        )\n    }\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/iterator/CloseableIterator.kt",
    "content": "package com.shicheeng.copymanga.util.iterator\n\nimport okhttp3.internal.closeQuietly\nimport java.io.Closeable\n\nclass CloseableIterator<T>(\n    private val upstream: Iterator<T>,\n    private val closeable: Closeable,\n) : Iterator<T>, Closeable {\n\n    private var isClose = false\n\n    override fun hasNext(): Boolean {\n        val result = upstream.hasNext()\n        if (!result) {\n            close()\n        }\n        return result\n    }\n\n    override fun next(): T {\n        try {\n            return upstream.next()\n        } catch (e: NoSuchElementException) {\n            close()\n            throw e\n        }\n    }\n\n    override fun close() {\n        if (!isClose){\n            closeable.closeQuietly()\n            isClose = true\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/iterator/MappingIterator.kt",
    "content": "package com.shicheeng.copymanga.util.iterator\n\nclass MappingIterator<T, R>(\n    private val upstream: Iterator<T>,\n    private val mapper: (T) -> R,\n) : Iterator<R> {\n\n    override fun hasNext(): Boolean {\n        return upstream.hasNext()\n    }\n\n    override fun next(): R {\n       return mapper(upstream.next())\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/util/progress/TimeLeftEstimator.kt",
    "content": "package com.shicheeng.copymanga.util.progress\n\nimport android.os.SystemClock\nimport java.util.concurrent.TimeUnit\nimport kotlin.math.roundToInt\nimport kotlin.math.roundToLong\n\nprivate const val MIN_ESTIMATE_TICKS = 4\nprivate const val NO_TIME = -1L\n\nclass TimeLeftEstimator {\n\n\tprivate var times = ArrayList<Int>()\n\tprivate var lastTick: Tick? = null\n\tprivate val tooLargeTime = TimeUnit.DAYS.toMillis(1)\n\n\tfun tick(value: Int, total: Int) {\n\t\tif (total < 0) {\n\t\t\temptyTick()\n\t\t\treturn\n\t\t}\n\t\tif (lastTick?.value == value) {\n\t\t\treturn\n\t\t}\n\t\tval tick = Tick(value, total, SystemClock.elapsedRealtime())\n\t\tlastTick?.let {\n\t\t\tval ticksCount = value - it.value\n\t\t\ttimes.add(((tick.time - it.time) / ticksCount.toDouble()).roundToInt())\n\t\t}\n\t\tlastTick = tick\n\t}\n\n\tfun emptyTick() {\n\t\tlastTick = null\n\t}\n\n\tfun getEstimatedTimeLeft(): Long {\n\t\tval progress = lastTick ?: return NO_TIME\n\t\tif (times.size < MIN_ESTIMATE_TICKS) {\n\t\t\treturn NO_TIME\n\t\t}\n\t\tval timePerTick = times.average()\n\t\tval ticksLeft = progress.total - progress.value\n\t\tval eta = (ticksLeft * timePerTick).roundToLong()\n\t\treturn if (eta < tooLargeTime) eta else NO_TIME\n\t}\n\n\tfun getEta(): Long {\n\t\tval etl = getEstimatedTimeLeft()\n\t\treturn if (etl == NO_TIME) NO_TIME else System.currentTimeMillis() + etl\n\t}\n\n\tprivate class Tick(\n\t\t@JvmField val value: Int,\n\t\t@JvmField val total: Int,\n\t\t@JvmField val time: Long,\n\t)\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/view/ExpandSelectionBar.kt",
    "content": "package com.shicheeng.copymanga.view\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.View\nimport android.widget.AdapterView\nimport android.widget.LinearLayout\nimport androidx.appcompat.widget.ListPopupWindow\nimport com.shicheeng.copymanga.R\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.databinding.MaganSelectBarBinding\n\nclass ExpandSelectionBar(context: Context, attributeSet: AttributeSet) :\n    LinearLayout(context, attributeSet, 0, 0) {\n\n    private val itemView =\n        View.inflate(context, R.layout.magan_select_bar, this)\n    private val binding = MaganSelectBarBinding.bind(itemView)\n    private val listPopupWindowSort = ListPopupWindow(\n        context, null,\n        androidx.appcompat.R.attr.listPopupWindowStyle\n    )\n    private var _onClick: ((MangaSortBean?) -> Unit)? = null\n\n    var menuList: List<MangaSortBean>? = null\n        set(value) {\n            if (value != null) {\n                field = value\n            }\n        }\n\n    fun setOnItemClickListener(onClickListener: (MangaSortBean?) -> Unit) {\n        this._onClick = onClickListener\n    }\n\n    var tipText: CharSequence\n        get() = binding.selectBarText.text\n        set(value) {\n            binding.selectBarText.text = value\n        }\n\n    var autoCompleteText: CharSequence? = binding.auto2.text.toString()\n        set(value) {\n            if (value != null) {\n                field = value\n                binding.auto2.setText(value)\n            }\n        }\n\n    init {\n        listPopupWindowSort.anchorView = binding.selectBarExpandMenu\n        binding.auto2.setOnClickListener {\n            listPopupWindowSort.show()\n        }\n        listPopupWindowSort.setOnItemClickListener { _: AdapterView<*>, _: View, i: Int, _: Long ->\n            val name = menuList?.get(i)?.pathName\n            _onClick?.invoke(menuList?.get(i))\n            binding.auto2.setText(name)\n            listPopupWindowSort.dismiss()\n        }\n        context.theme.obtainStyledAttributes(\n            attributeSet,\n            R.styleable.ExpandSelectionBar,\n            0, 0\n        ).apply {\n            try {\n                binding.selectBarText.text = getString(R.styleable.ExpandSelectionBar_tipText)\n                binding.selectBarExpandMenu.hint =\n                    getString(R.styleable.ExpandSelectionBar_hintText)\n            } finally {\n                recycle()\n            }\n        }\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/view/HeadLineView.java",
    "content": "package com.shicheeng.copymanga.view;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport android.content.res.TypedArray;\nimport android.util.AttributeSet;\nimport android.view.View;\nimport android.widget.LinearLayout;\nimport android.widget.TextView;\n\nimport androidx.annotation.Nullable;\n\nimport com.shicheeng.copymanga.R;\n\npublic class HeadLineView extends LinearLayout {\n\n    private TextView handLineText;\n    private LinearLayout linearLayout;\n    private onHeadClickListener onHeadClickListener;\n\n    private void initView(Context context){\n        View.inflate(context, R.layout.manga_headline_1,this);\n        handLineText = findViewById(R.id.title_id);\n        linearLayout = findViewById(R.id.linear_id);\n        linearLayout.setOnClickListener(new OnClickListener() {\n            @Override\n            public void onClick(View view) {\n                onHeadClickListener.onClick(view);\n            }\n        });\n    }\n\n    public HeadLineView(Context context) {\n        super(context);\n        initView(context);\n    }\n\n    public HeadLineView(Context context, @Nullable AttributeSet attrs) {\n        super(context, attrs);\n        initView(context);\n        @SuppressLint(\"Recycle\") TypedArray array =\n                context.obtainStyledAttributes(attrs,R.styleable.HeadLineView);\n        String title = array.getString(R.styleable.HeadLineView_headTitle);\n        setHandLineText(title);\n    }\n\n\n    public void setHandLineText(int redID){\n        handLineText.setText(redID);\n    }\n\n    public void setHandLineText(String text){\n        handLineText.setText(text);\n    }\n\n    public String getHandLineText(){\n        return handLineText.getText().toString();\n    }\n\n    public void setOnHeadClickListener(HeadLineView.onHeadClickListener onHeadClickListener) {\n        this.onHeadClickListener = onHeadClickListener;\n    }\n\n    public interface onHeadClickListener{\n        void onClick(View view);\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/view/MyRecyclerView.kt",
    "content": "package com.shicheeng.copymanga.view\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport androidx.recyclerview.widget.LinearLayoutManager\nimport androidx.recyclerview.widget.RecyclerView\nimport com.shicheeng.copymanga.util.FirstSnapHelper\n\n\nclass MyRecyclerView @JvmOverloads constructor(\n    context: Context,\n    attributeSet: AttributeSet? = null,\n) : RecyclerView(context, attributeSet) {\n\n    private val layout = LinearLayoutManager(context, HORIZONTAL, false)\n    private val spanHelper = FirstSnapHelper()\n\n    init {\n        layoutManager = layout\n        spanHelper.attachToRecyclerView(this)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/view/SummaryText.kt",
    "content": "package com.shicheeng.copymanga.view\n\nimport android.animation.AnimatorSet\nimport android.animation.ValueAnimator\nimport android.content.Context\nimport android.text.TextUtils\nimport android.util.AttributeSet\nimport androidx.annotation.AttrRes\nimport androidx.appcompat.widget.AppCompatTextView\nimport androidx.core.view.doOnNextLayout\nimport androidx.interpolator.view.animation.FastOutSlowInInterpolator\nimport com.shicheeng.copymanga.util.animatorDurationScale\nimport kotlin.math.roundToLong\n\n/**\n * 修改自Tachiyomi。\n *\n * 展开文字控件\n */\nclass SummaryText @JvmOverloads constructor(\n    context: Context,\n    attrs: AttributeSet? = null,\n    @AttrRes defStyleAttr: Int = 0,\n) : AppCompatTextView(context, attrs, defStyleAttr) {\n\n    var expanded = false\n        set(value) {\n            if (field != value) {\n                field = value\n                updateExpandState()\n            }\n        }\n    private var recalculateHeights = false\n    private var descExpandedHeight = -1\n    private var descShrunkHeight = -1\n    private var animatorSet: AnimatorSet? = null\n\n\n    private fun updateExpandState() {\n        val initialSetup = maxHeight < 0\n\n        val maxHeightTarget = if (expanded) descExpandedHeight else descShrunkHeight\n        val maxHeightStart = if (initialSetup) maxHeightTarget else maxHeight\n        val descMaxHeightAnimator = ValueAnimator().apply {\n            setIntValues(maxHeightStart, maxHeightTarget)\n            addUpdateListener {\n                maxHeight = it.animatedValue as Int\n            }\n        }\n\n        var pastHalf = false\n        val toggleTarget = if (expanded) 1F else 0F\n        val toggleStart = if (initialSetup) {\n            toggleTarget\n        } else {\n            translationY / height\n        }\n        val toggleAnimator = ValueAnimator().apply {\n            setFloatValues(toggleStart, toggleTarget)\n            addUpdateListener {\n\n                // Update non-animatable objects mid-animation makes it feel less abrupt\n                if (it.animatedFraction >= 0.5F && !pastHalf) {\n                    pastHalf = true\n                    ellipsizeWhenNeeded()\n                }\n            }\n        }\n\n        animatorSet?.cancel()\n        animatorSet = AnimatorSet().apply {\n            interpolator = FastOutSlowInInterpolator()\n            duration = (TOGGLE_ANIM_DURATION * context.animatorDurationScale).roundToLong()\n            playTogether(toggleAnimator, descMaxHeightAnimator)\n            start()\n        }\n\n    }\n\n\n    private fun ellipsizeWhenNeeded() {\n        return if (!expanded) {\n            ellipsize = TextUtils.TruncateAt.END\n        } else {\n            ellipsize = null\n        }\n    }\n\n    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {\n        // Wait until parent view has determined the exact width\n        // because this affect the description line count\n        val measureWidthFreely = MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.EXACTLY\n        if (!recalculateHeights || measureWidthFreely) {\n            super.onMeasure(widthMeasureSpec, heightMeasureSpec)\n            return\n        }\n        recalculateHeights = false\n\n        // Measure with expanded lines\n        maxLines = Int.MAX_VALUE\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec)\n        descExpandedHeight = measuredHeight\n\n        // Measure with shrunk lines\n        maxLines = SHRUNK_DESC_MAX_LINES\n        super.onMeasure(widthMeasureSpec, heightMeasureSpec)\n        descShrunkHeight = measuredHeight\n    }\n\n\n    init {\n        recalculateHeights = true\n        doOnNextLayout {\n            updateExpandState()\n        }\n        if (!isInLayout) {\n            requestLayout()\n        }\n        minLines = DESC_MIN_LINES\n        setOnClickListener { expanded = !expanded }\n    }\n\n}\n\nprivate const val TOGGLE_ANIM_DURATION = 300L\n\nprivate const val DESC_MIN_LINES = 2\nprivate const val SHRUNK_DESC_MAX_LINES = 3"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/view/TransitionTextview.kt",
    "content": "package com.shicheeng.copymanga.view\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport android.view.Gravity\nimport android.view.ViewGroup\nimport androidx.annotation.StringRes\nimport androidx.core.view.isVisible\nimport androidx.transition.Fade\nimport androidx.transition.Slide\nimport androidx.transition.TransitionManager\nimport androidx.transition.TransitionSet\nimport com.google.android.material.textview.MaterialTextView\n\nclass TransitionTextview @JvmOverloads constructor(\n    context: Context,\n    attributeSet: AttributeSet? = null,\n    defStyleAttr: Int = 0,\n) : MaterialTextView(context, attributeSet, defStyleAttr) {\n\n    private val hideRunnable = Runnable {\n        hide()\n    }\n\n    fun show(message: CharSequence) {\n        removeCallbacks(hideRunnable)\n        text = message\n        setupTransition()\n        isVisible = true\n    }\n\n    fun show(@StringRes resID: Int) {\n        show(context.getString(resID))\n    }\n\n    fun tip(message: CharSequence, duration: Long) {\n        show(message)\n        postDelayed(hideRunnable, duration)\n    }\n\n    override fun onDetachedFromWindow() {\n        removeCallbacks(hideRunnable)\n        super.onDetachedFromWindow()\n    }\n\n    fun hide() {\n        removeCallbacks(hideRunnable)\n        setupTransition()\n        isVisible = false\n    }\n\n    private fun setupTransition() {\n        val parentView = parent as? ViewGroup ?: return\n        val transition = TransitionSet()\n            .setOrdering(TransitionSet.ORDERING_TOGETHER)\n            .addTarget(this)\n            .addTransition(Slide(Gravity.TOP))\n            .addTransition(Fade())\n        TransitionManager.beginDelayedTransition(parentView, transition)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/view/control/ReaderControl.kt",
    "content": "package com.shicheeng.copymanga.view.control\n\nimport android.view.SoundEffectConstants\nimport android.view.View\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.GestureHelper as GridTouchHelper\n\nclass ReaderControl(\n    private val listener: ControlDelegateListener,\n    private val settingPref: SettingPref,\n) {\n    private val isQuickTouchEnable get() = settingPref.hyperTouch.value\n\n    fun onGridTouch(area: Int, view: View) {\n        when (area) {\n            GridTouchHelper.AREA_CENTER -> {\n                listener.hide()\n                view.playSoundEffect(SoundEffectConstants.CLICK)\n            }\n\n            GridTouchHelper.AREA_TOP -> if (isQuickTouchEnable) {\n                listener.scrollPage(-1)\n                view.playSoundEffect(SoundEffectConstants.NAVIGATION_UP)\n            }\n\n            GridTouchHelper.AREA_LEFT -> {\n                listener.scrollPage(if (isReaderTapsReversed()) -1 else 1)\n                view.playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT)\n            }\n\n            GridTouchHelper.AREA_BOTTOM -> if (isQuickTouchEnable) {\n                listener.scrollPage(1)\n                view.playSoundEffect(SoundEffectConstants.NAVIGATION_DOWN)\n            }\n\n            GridTouchHelper.AREA_RIGHT -> {\n                listener.scrollPage(if (isReaderTapsReversed()) 1 else -1)\n                view.playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT)\n            }\n        }\n    }\n\n    private fun isReaderTapsReversed(): Boolean {\n        return listener.readerMode == ReaderMode.STANDARD || listener.readerMode == ReaderMode.WEBTOON\n    }\n\n    interface ControlDelegateListener {\n        val readerMode: ReaderMode?\n        fun scrollPage(delta: Int)\n        fun hide()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/view/list/SpaceItem.kt",
    "content": "package com.shicheeng.copymanga.view.list\n\nimport android.graphics.Rect\nimport android.view.View\nimport androidx.annotation.Px\nimport androidx.recyclerview.widget.RecyclerView\n\nclass SpaceItem(@Px private val spacingDp: Int) : RecyclerView.ItemDecoration() {\n    override fun getItemOffsets(\n        outRect: Rect,\n        view: View,\n        parent: RecyclerView,\n        state: RecyclerView.State,\n    ) {\n        outRect.set(spacingDp, spacingDp, spacingDp, spacingDp)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/AuthorMangaViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.SavedStateHandle\nimport androidx.lifecycle.ViewModel\nimport com.shicheeng.copymanga.resposity.AuthorsMangaRepository\nimport com.shicheeng.copymanga.resposity.logD\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.filterNotNull\nimport kotlinx.coroutines.flow.flatMapLatest\nimport javax.inject.Inject\n\n@HiltViewModel\nclass AuthorMangaViewModel @Inject constructor(\n    savedStateHandle: SavedStateHandle,\n    authorsMangaRepository: AuthorsMangaRepository,\n) : ViewModel() {\n    private val authorPathWordNow: String? = savedStateHandle[\"author_path_word\"]\n    private val _authorPathWord = MutableStateFlow(authorPathWordNow)\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val list = _authorPathWord\n        .filter {\n            !it.isNullOrBlank() && it.isNotEmpty()\n        }.filterNotNull()\n        .flatMapLatest {\n            it.logD()\n            authorsMangaRepository.fetchMangaByPathWord(it)\n        }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/CommentViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.SavedStateHandle\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.resposity.ComicCommentRepository\nimport com.shicheeng.copymanga.resposity.LoginTokenRepository\nimport com.shicheeng.copymanga.util.RetryTrigger\nimport com.shicheeng.copymanga.util.SendUIState\nimport com.shicheeng.copymanga.util.retryableFlow\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.FlowPreview\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.combine\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.filterNotNull\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@OptIn(ExperimentalCoroutinesApi::class)\n@HiltViewModel\nclass CommentViewModel @Inject constructor(\n    savedStateHandle: SavedStateHandle,\n    private val repository: ComicCommentRepository,\n    private val loginTokenRepository: LoginTokenRepository,\n) : ViewModel() {\n\n    private val uuid: String? = savedStateHandle[\"uuid_comic\"]\n    private val _comicUUID = MutableStateFlow(uuid)\n\n    private val _comicText = MutableStateFlow(\"\")\n\n    val loginIsExpired = loginTokenRepository.isExpiredFlow\n        .filterNotNull()\n        .stateIn(\n            scope = viewModelScope,\n            initialValue = loginTokenRepository.isExpired,\n            started = SharingStarted.Eagerly\n        )\n\n    val retry = RetryTrigger()\n    private val commentPushEvent = combine(_comicUUID, _comicText) { uuid, text ->\n        if (uuid != null) CombineComicDataModel(uuid, text) else null\n    }.filterNotNull().filter {\n        it.ensureTextNoNull()\n    }.flatMapLatest {\n        repository.push(it.uuid, it.text)\n    }\n\n    @OptIn(FlowPreview::class)\n    val commentPush = retryableFlow(retry) {\n        commentPushEvent\n    }.stateIn(\n        scope = viewModelScope,\n        initialValue = SendUIState.Idle,\n        started = SharingStarted.Eagerly\n    )\n\n\n    val comments = _comicUUID\n        .filter { !it.isNullOrBlank() && it.isNotEmpty() }\n        .filterNotNull()\n        .flatMapLatest {\n            repository.loadComment(it)\n        }.cachedIn(viewModelScope)\n\n\n    /**\n     * 发送消息\n     * @param text 消息文本\n     * @author ShihCheeng\n     */\n    fun sendComment(text: String) = viewModelScope.launch {\n        _comicText.emit(text)\n    }\n\n    data class CombineComicDataModel(\n        val uuid: String,\n        val text: String,\n    ) {\n        fun ensureTextNoNull() = uuid.isNotEmpty()\n                && uuid.isNotBlank()\n                && text.isNotBlank()\n                && text.isNotEmpty()\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/DownloadViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.domin.DownloadFileDetectUtil\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.stateIn\nimport javax.inject.Inject\n\n@HiltViewModel\nclass DownloadViewModel @Inject constructor(\n    fileDetectUtil: DownloadFileDetectUtil,\n) : ViewModel() {\n\n\n    val list = fileDetectUtil.findDownloadManga()\n        .stateIn(\n            scope = viewModelScope,\n            started = SharingStarted.Eagerly,\n            initialValue = emptyList()\n        )\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/ExploreMangaViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.PagingData\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.data.MangaSortBean\nimport com.shicheeng.copymanga.data.finished.Item\nimport com.shicheeng.copymanga.json.MangaSortJson\nimport com.shicheeng.copymanga.resposity.MangaFilterRepository\nimport com.shicheeng.copymanga.resposity.logD\nimport com.shicheeng.copymanga.util.UIState\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.flow.combine\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@OptIn(ExperimentalCoroutinesApi::class)\n@HiltViewModel\nclass ExploreMangaViewModel @Inject constructor(\n    private val repository: MangaFilterRepository,\n) : ViewModel() {\n\n\n    private val _uiState = MutableStateFlow<UIState<List<MangaSortBean>>>(UIState.Loading)\n    val uiState = _uiState.asStateFlow()\n\n    val order = MutableStateFlow<String?>(null)\n    val themeType = MutableStateFlow<String?>(null)\n    val top = MutableStateFlow<String?>(null)\n\n    val loadFilterResult: Flow<PagingData<Item>> = combine(order, themeType, top) { t1, t2, t3 ->\n        FilterKeyModel(order = t1, theme = t2, top = t3)\n    }.flatMapLatest {\n        repository.filterMangas(top = it.top, theme = it.theme, ordering = it.order)\n    }.cachedIn(viewModelScope)\n\n\n    private val _showBottomSheet = MutableStateFlow(MangaSortJson.ORDER)\n    val showBottomSheet = _showBottomSheet.asStateFlow()\n\n    init {\n        loadData()\n    }\n\n    fun loadData() = viewModelScope.launch {\n        _uiState.emit(UIState.Loading)\n        try {\n            val listTheme = repository.theme()\n            _uiState.emit(UIState.Success(listTheme))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            _uiState.emit(UIState.Error(e))\n        }\n    }\n\n    fun filterOn(\n        order: String? = null,\n        theme: String? = null,\n        top: String? = null,\n    ) = viewModelScope.launch {\n        this@ExploreMangaViewModel.order.emit(order)\n        this@ExploreMangaViewModel.themeType.emit(theme)\n        this@ExploreMangaViewModel.top.emit(top)\n    }\n\n    fun showThemeFilterList() {\n        _showBottomSheet.tryEmit(MangaSortJson.THEME)\n\n    }\n\n    fun showTopFilterList() {\n        _showBottomSheet.tryEmit(MangaSortJson.PATH)\n\n    }\n\n    fun showOrderFilterList() {\n        _showBottomSheet.tryEmit(MangaSortJson.ORDER)\n    }\n\n    data class FilterKeyModel(\n        val order: String?,\n        val theme: String?,\n        val top: String?,\n    )\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/HistoryViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass HistoryViewModel @Inject constructor(\n    private val history: MangaHistoryRepository,\n) : ViewModel() {\n\n    val historyList = history.allHistoryDao.stateIn(\n        scope = viewModelScope,\n        started = SharingStarted.Eagerly,\n        initialValue = emptyList()\n    )\n\n    fun deleteHistory(mangaHistoryDataModel: MangaHistoryDataModel) = viewModelScope.launch {\n        history.deleteSingleHistory(mangaHistoryDataModel)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/HomeViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport android.util.Log\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.data.MainPageDataModel\nimport com.shicheeng.copymanga.resposity.MangaMainPageRepository\nimport com.shicheeng.copymanga.util.UIState\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass HomeViewModel @Inject constructor(\n    private val mangaMainPageRepository: MangaMainPageRepository,\n) : ViewModel() {\n\n\n    private val _uiState = MutableStateFlow<UIState<MainPageDataModel>>(UIState.Loading)\n    val uiState = _uiState.asStateFlow()\n\n    init {\n        loadData()\n    }\n\n    fun loadData() = viewModelScope.launch {\n        _uiState.emit(UIState.Loading)\n        try {\n            val mainData = mangaMainPageRepository.fetchMainData()\n            Log.d(\"TAG\", \"loadData: $mainData\")\n            _uiState.emit(UIState.Success(mainData))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            _uiState.emit(UIState.Error(e))\n        }\n    }\n\n\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/LoginPersonalListViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.data.login.LocalLoginDataModel\nimport com.shicheeng.copymanga.resposity.LoginRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass LoginPersonalListViewModel @Inject constructor(\n    private val repository: LoginRepository,\n) : ViewModel() {\n\n    val personalList = repository\n        .getAllLoginInstance()\n        .stateIn(\n            scope = viewModelScope,\n            started = SharingStarted.Eagerly,\n            initialValue = emptyList()\n        )\n\n    fun delete(localLoginDataModel: LocalLoginDataModel) = viewModelScope.launch {\n        repository.deleteOneInstance(localLoginDataModel)\n    }\n\n    fun selectUUId(uuid: String) = viewModelScope.launch {\n        repository.selectOne(uuid)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/MainViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.resposity.LoginRepository\nimport com.shicheeng.copymanga.util.collectRepeatLifecycle\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.conflate\nimport kotlinx.coroutines.flow.distinctUntilChanged\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass MainViewModel @Inject constructor(\n    loginRepository: LoginRepository,\n) : ViewModel() {\n\n    val loginInfoStatus = loginRepository.testLoginStatus()\n        .distinctUntilChanged()\n        .conflate()\n        .stateIn(\n            scope = viewModelScope,\n            started = SharingStarted.Lazily,\n            initialValue = null\n        )\n    val showSnackBar = MutableStateFlow(false)\n\n    init {\n        viewModelScope.launch {\n            loginInfoStatus.collectLatest {\n                showSnackBar.emit(it != null)\n            }\n        }\n    }\n\n    fun dismissShack() = viewModelScope.launch {\n        showSnackBar.emit(false)\n    }\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/MangaHotListViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.pagingsource.HotPagingSource\nimport com.shicheeng.copymanga.resposity.MangaHotRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport javax.inject.Inject\n\n@HiltViewModel\nclass MangaHotListViewModel @Inject constructor(\n    repository: MangaHotRepository,\n) : ViewModel() {\n\n    val hotMangaList = Pager(config = PagingConfig(pageSize = 21)) {\n        HotPagingSource(repository)\n    }.flow.cachedIn(viewModelScope)\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/MangaInfoViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.SavedStateHandle\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.ViewModelProvider\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport com.shicheeng.copymanga.resposity.MangaInfoRepository\nimport com.shicheeng.copymanga.server.download.woker.DownloadedWorker\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport com.shicheeng.copymanga.util.RetryTrigger\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.util.retryableFlow\nimport dagger.assisted.AssistedFactory\nimport dagger.assisted.AssistedInject\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.FlowPreview\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.flow.collectLatest\nimport kotlinx.coroutines.flow.combine\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.flow.update\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass MangaInfoViewModel @Inject constructor(\n    savedStateHandle: SavedStateHandle,\n    private val repository: MangaHistoryRepository,\n    private val infoRepository: MangaInfoRepository,\n    private val setting: SettingPref,\n    private val downloadedWorker: DownloadedWorker.Caller,\n) : ViewModel() {\n\n    val pathWord: String = savedStateHandle[\"path_word\"] ?: error(\"无关键词\")\n    private val _historyFlowChapter = repository.fetchMangaChapterByPathWordFlow(pathWord)\n\n    //Chapter and Information\n    private val _chapter = MutableStateFlow<UIState<List<LocalChapter>>>(UIState.Loading)\n    val chapters = _chapter.asStateFlow()\n    private val _mangaInfo = MutableStateFlow<UIState<MangaHistoryDataModel>>(UIState.Loading)\n    val mangaInfo = _mangaInfo.asStateFlow()\n\n    private val _selectedChapter = MutableStateFlow<List<LocalChapter>>(emptyList())\n    val selectChapter = _selectedChapter.asStateFlow()\n\n    val lastWatchChapter = combine(\n        flow = _chapter,\n        flow2 = _mangaInfo\n    ) { uiStateChapter: UIState<List<LocalChapter>>, uiStateInfo: UIState<MangaHistoryDataModel> ->\n        when {\n            uiStateChapter is UIState.Success && uiStateInfo is UIState.Success -> {\n                if (uiStateChapter.content.isNotEmpty()) {\n                    uiStateChapter.content[uiStateInfo.content.positionChapter]\n                } else null\n            }\n\n            else -> {\n                null\n            }\n        }\n    }.stateIn(\n        scope = viewModelScope,\n        started = SharingStarted.Eagerly,\n        initialValue = null\n    )\n\n    private val collectRetryTrigger = RetryTrigger()\n\n    @OptIn(FlowPreview::class)\n    val lastWebLookedChapter = retryableFlow(retryTrigger = collectRetryTrigger) {\n        infoRepository.fetchComicWebHistory(pathWord)\n    }.stateIn(\n        started = SharingStarted.Eagerly,\n        initialValue = null,\n        scope = viewModelScope\n    )\n\n\n    init {\n        onInfoLoad()\n        onChapterLoad()\n        viewModelScope.launch {\n            repository.fetchMangaChapterByPathWordFlow(pathWord).collectLatest {\n                it?.let {\n                    _chapter.emit(UIState.Success(it))\n                }\n            }\n\n        }\n    }\n\n    fun onInfoLoad() = viewModelScope.launch {\n        _chapter.emit(UIState.Loading)\n        try {\n            val mangaInfoContent = infoRepository.fetchMangaInfo(pathWord)\n            _mangaInfo.emit(UIState.Success(mangaInfoContent))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            _mangaInfo.emit(UIState.Error(e))\n        }\n    }\n\n    fun selectItem(item: LocalChapter, isAdd: Boolean) = viewModelScope.launch {\n        _selectedChapter.update {\n            if (isAdd) {\n                it.plus(item)\n            } else {\n                it.minus(item)\n            }\n        }\n    }\n\n    fun deselectedAllItem() {\n        _selectedChapter.update {\n            emptyList()\n        }\n    }\n\n    fun selectFirst5(): List<LocalChapter>? {\n        return if (chapters.value is UIState.Success) {\n            (chapters.value as UIState.Success).content.take(5)\n        } else null\n    }\n\n    fun selectLast5(): List<LocalChapter>? {\n        return if (chapters.value is UIState.Success) {\n            (chapters.value as UIState.Success).content.takeLast(5)\n        } else null\n    }\n\n    private fun onChapterLoad() = viewModelScope.launch {\n        try {\n            _chapter.emit(UIState.Loading)\n            val mangaChapter = infoRepository.fetchMangaChapters(pathWord)\n            _chapter.emit(UIState.Success(mangaChapter))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            _chapter.emit(UIState.Error(e))\n        }\n    }\n\n    fun chapterLoadForce() = viewModelScope.launch {\n        try {\n            _chapter.emit(UIState.Loading)\n            _mangaInfo.emit(UIState.Success(infoRepository.fetchMangaInfoForce(pathWord)))\n            _chapter.emit(UIState.Success(infoRepository.fetchMangaChaptersForce(pathWord)))\n        } catch (e: Exception) {\n            e.printStackTrace()\n            _chapter.emit(UIState.Error(e))\n        }\n    }\n\n    fun comicUpdate(enable: Boolean) = viewModelScope.launch {\n        repository.getHistoryByMangaPathWord(pathWord)?.let {\n            val newData = it.copy(isSubscribe = enable)\n            repository.update(newData)\n            _mangaInfo.emit(UIState.Success(newData))\n        }\n    }\n\n    fun comicMarkRead(isRead: Boolean) = viewModelScope.launch(Dispatchers.IO) {\n        _selectedChapter.collectLatest { localChapters ->\n            localChapters.map {\n                it.copy(\n                    isReadFinish = isRead,\n                    readIndex = if (isRead) it.readIndex else 0\n                )\n            }.let {\n                repository.updateLocalChapter(it)\n            }\n        }\n    }\n\n    fun comicAddWebLib(mangaUUID: String, add: Boolean) = viewModelScope.launch {\n        infoRepository.collect(mangaUUID, add)\n        collectRetryTrigger.retry()\n    }\n\n    fun enableComicUpdate(enable: Boolean) {\n        setting.enableComicsUpdateFetch(enable)\n    }\n\n    fun downloadManga(chapters: Array<String>) = viewModelScope.launch {\n        downloadedWorker.download(pathWord, chapters)\n    }\n\n}\n\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/MangaNewestListViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.pagingsource.NewestPagingSource\nimport com.shicheeng.copymanga.resposity.MangaNewestRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport javax.inject.Inject\n\n@HiltViewModel\nclass MangaNewestListViewModel @Inject constructor(\n    newestRepository: MangaNewestRepository,\n) : ViewModel() {\n    val list = Pager(\n        config = PagingConfig(pageSize = 21),\n    ) {\n        NewestPagingSource(newestRepository)\n    }.flow.cachedIn(viewModelScope)\n\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/MangaRecommendListViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.Pager\nimport androidx.paging.PagingConfig\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.pagingsource.RecommendPagingSource\nimport com.shicheeng.copymanga.resposity.MangaRecommendRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport javax.inject.Inject\n\n@HiltViewModel\nclass MangaRecommendListViewModel @Inject constructor(\n    repository: MangaRecommendRepository,\n) : ViewModel() {\n\n    val recommendMangaList = Pager(config = PagingConfig(pageSize = 21)) {\n        RecommendPagingSource(repository)\n    }.flow.cachedIn(viewModelScope)\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/PersonalDetailViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.resposity.LoginDetailRepository\nimport com.shicheeng.copymanga.util.RetryTrigger\nimport com.shicheeng.copymanga.util.UIState\nimport com.shicheeng.copymanga.util.retryableFlow\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.FlowPreview\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.onStart\nimport kotlinx.coroutines.flow.stateIn\nimport javax.inject.Inject\n\n@HiltViewModel\nclass PersonalDetailViewModel @Inject constructor(\n    private val loginDetailRepository: LoginDetailRepository,\n) : ViewModel() {\n\n    private val retryTrigger = RetryTrigger()\n\n    @OptIn(FlowPreview::class)\n    val data = retryableFlow(retryTrigger) {\n        loginDetailRepository.detail()\n            .onStart {\n                UIState.Loading\n            }\n    }.stateIn(\n        scope = viewModelScope,\n        initialValue = UIState.Loading,\n        started = SharingStarted.Eagerly\n    )\n\n    fun retry() = retryTrigger.retry()\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/PersonalViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.resposity.LoginRepository\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.filter\nimport kotlinx.coroutines.flow.filterNotNull\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport javax.inject.Inject\n\n@HiltViewModel\nclass PersonalViewModel @Inject constructor(\n    private val loginRepository: LoginRepository,\n    settingPref: SettingPref,\n) : ViewModel() {\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val user = settingPref.loginPersonalFlow\n        .stateIn(\n            scope = viewModelScope,\n            initialValue = settingPref.loginPerson,\n            started = SharingStarted.Eagerly\n        )\n        .filter { !it.isNullOrBlank() && it.isNotEmpty() }\n        .filterNotNull()\n        .flatMapLatest {\n            loginRepository.getUserByUUid(it)\n        }.stateIn(\n            scope = viewModelScope,\n            initialValue = null,\n            started = SharingStarted.Eagerly\n        )\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/RankViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.resposity.MangaRankRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport javax.inject.Inject\n\n@HiltViewModel\nclass RankViewModel @Inject constructor(\n    rankRepository: MangaRankRepository,\n) : ViewModel() {\n\n    val dayRank = rankRepository.fetchMangaRank(\"day\").cachedIn(viewModelScope)\n    val weekRank = rankRepository.fetchMangaRank(\"week\").cachedIn(viewModelScope)\n    val monthRank = rankRepository.fetchMangaRank(\"month\").cachedIn(viewModelScope)\n    val totalRank = rankRepository.fetchMangaRank(\"total\").cachedIn(viewModelScope)\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/ReaderViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.annotation.WorkerThread\nimport androidx.lifecycle.SavedStateHandle\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.data.MangaHistoryDataModel\nimport com.shicheeng.copymanga.data.MangaReaderPage\nimport com.shicheeng.copymanga.data.MangaState\nimport com.shicheeng.copymanga.data.ReaderContent\nimport com.shicheeng.copymanga.data.ReaderState\nimport com.shicheeng.copymanga.data.local.LocalChapter\nimport com.shicheeng.copymanga.data.local.toMangaState\nimport com.shicheeng.copymanga.fm.domain.ChapterLoader\nimport com.shicheeng.copymanga.fm.domain.PagerLoader\nimport com.shicheeng.copymanga.fm.reader.MangaLoader\nimport com.shicheeng.copymanga.fm.reader.ReaderMode\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport com.shicheeng.copymanga.resposity.MangaInfoRepository\nimport com.shicheeng.copymanga.ui.screen.setting.SettingPref\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.CoroutineExceptionHandler\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.CoroutineStart\nimport kotlinx.coroutines.Dispatchers\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.cancelAndJoin\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.asStateFlow\nimport kotlinx.coroutines.flow.update\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.runBlocking\nimport javax.inject.Inject\nimport kotlin.collections.set\nimport kotlin.coroutines.CoroutineContext\nimport kotlin.coroutines.EmptyCoroutineContext\n\nprivate const val MAX_LOAD_PAGER = 4\n\n/**\n * 重新设计ReaderViewModel\n */\n@HiltViewModel\nclass ReaderViewModel @Inject constructor(\n    savedStateHandle: SavedStateHandle,\n    private val repository: MangaHistoryRepository,\n    private val pagerLoader: PagerLoader,\n    private val settingPref: SettingPref,\n    private val mangaInfoRepository: MangaInfoRepository,\n    private val chapterLoader: ChapterLoader,\n) : ViewModel() {\n\n    private val mangaLoader = MangaLoader(savedStateHandle)\n    private val currentPathWord = mangaLoader.mangaPathWord\n    private val currentChapterUUID = mangaLoader.mangaChapterUUID\n\n    private val list by lazy {\n        runBlocking {\n            mangaInfoRepository.fetchMangaChapters(\n                pathWord = requireNotNull(mangaLoader.mangaPathWord),\n            )\n        }\n    }\n\n    private val initChapter = list.find { x -> x.uuid == currentChapterUUID } ?: list[0]\n    private var loadJob: Job? = null\n    private val chapters: LinkedHashMap<String, LocalChapter> get() = chapterLoader.chapters\n\n    private val _loadingCounter = MutableStateFlow(false)\n    val loadingCounter get() = _loadingCounter.asStateFlow()\n\n    private val _errorHandler = MutableStateFlow<Throwable?>(null)\n    val errorHandler get() = _errorHandler.asStateFlow()\n\n    val information = MutableStateFlow<ReaderState?>(null)\n    private val historyData = MutableStateFlow<MangaHistoryDataModel?>(null)\n    val state = MutableStateFlow(initChapter.toMangaState())\n    val mangaContent = MutableStateFlow(ReaderContent(emptyList(), null))\n    val readerModel = MutableStateFlow<ReaderMode?>(null)\n    val nextChapterLoadStateFlow = chapterLoader.nextChapterLoadingState.asStateFlow()\n\n    init {\n        loadImp()\n    }\n\n\n    fun retry() {\n        loadJob?.cancel()\n        loadImp()\n    }\n\n    private fun loadPrevNextChapter(uuid: String?, isNext: Boolean) {\n        loadJob = loadJop(Dispatchers.Default) {\n            chapterLoader.loadPrevNextChapter(list, uuid, isNext)\n            mangaContent.value = ReaderContent(chapterLoader.snapshot(), null)\n        }\n    }\n\n    private fun loadHistory(pathWord: String) = viewModelScope.launch {\n        val historyDataModel = repository.getHistoryByMangaPathWord(pathWord)\n        historyData.emit(historyDataModel)\n    }\n\n    fun getCurrentReaderState() = state.value\n\n    val currentChapterPage: List<MangaReaderPage>\n        get() {\n            val id = state.value.uuid\n            return chapterLoader.getPage(id)\n        }\n\n    fun onPagePositionChange(position: Int) {\n        val pages = mangaContent.value.list\n        pages.getOrNull(position)?.let {\n            state.update { mangaState ->\n                mangaState.copy(uuid = it.uuid ?: return, page = it.index)\n            }\n        }\n        onInfoChange()\n        if (pages.isEmpty() || loadJob?.isActive == true) {\n            return\n        }\n        if (position <= MAX_LOAD_PAGER) {\n            loadPrevNextChapter(pages.first().uuid, isNext = false)\n        }\n        if (position >= pages.size - MAX_LOAD_PAGER) {\n            loadPrevNextChapter(pages.last().uuid, isNext = true)\n        }\n    }\n\n\n    @WorkerThread\n    private fun onInfoChange() {\n        val state = getCurrentReaderState()\n        val chapter = state.uuid.let(chapters::get)\n        val positionChapter = list.indexOfFirst { it.uuid == state.uuid }\n        val readerState = ReaderState(\n            chapterName = chapter?.name,\n            subTime = chapter?.datetime_created,\n            uuid = chapter?.uuid,\n            totalPage = if (chapter == null) 0 else chapterLoader[chapter.uuid],\n            currentPage = state.page,\n            chapterPosition = positionChapter,\n            mangaName = historyData.value?.name\n        )\n        information.value = readerState\n        viewModelScope.launch {\n            val newHistoryData = historyData.value\n                ?.copy(\n                    positionPage = state.page,\n                    positionChapter = positionChapter,\n                    time = System.currentTimeMillis()\n                )\n            if (newHistoryData != null) {\n                repository.updateAsync(newHistoryData)\n            }\n        }\n    }\n\n    fun saveCurrentState(nowState: MangaState? = null) {\n        if (nowState != null) {\n            state.value = nowState\n        }\n    }\n\n\n    fun switchMode(readerMode: ReaderMode) = viewModelScope.launch {\n        readerModel.value = readerMode\n        mangaContent.value.run {\n            mangaContent.value = copy(state = getCurrentReaderState())\n        }\n        val renew = historyData.value?.copy(readerModeId = readerMode.id) ?: return@launch\n        repository.update(renew)\n        historyData.emit(renew)\n    }\n\n    fun switchChapter(uuid: String?) {\n        if (uuid != null) {\n            val prevJob = loadJob\n            loadJob = loadJop(Dispatchers.Default) {\n                prevJob?.cancelAndJoin()\n                mangaContent.value = ReaderContent(emptyList(), null)\n                chapterLoader.loadSingleChapter(initChapter.comicPathWord, uuid)\n                mangaContent.value = ReaderContent(chapterLoader.snapshot(), MangaState(uuid, 0))\n            }\n        }\n    }\n\n    fun loadNextPrvChapter(uuid: String?, isNext: Boolean) {\n        if (uuid != null) {\n            val prevJob = loadJob\n            loadJob = loadJop(Dispatchers.Default) {\n                prevJob?.cancelAndJoin()\n                mangaContent.value = ReaderContent(emptyList(), null)\n                val predicate: (LocalChapter) -> Boolean = { it.uuid == uuid }\n                val index = if (isNext) {\n                    list.indexOfFirst(predicate)\n                } else {\n                    list.indexOfLast(predicate)\n                }\n                if (index == -1) return@loadJop\n                val newChapter =\n                    list.getOrNull(if (isNext) index + 1 else index - 1) ?: return@loadJop\n                switchChapter(newChapter.uuid)\n                mangaContent.value = ReaderContent(chapterLoader.snapshot(), MangaState(uuid, 0))\n            }\n        }\n    }\n\n    fun saveLocalChapterState(int: Int) {\n        viewModelScope.launch {\n            val currentChapter =\n                list.find { it.uuid == getCurrentReaderState().uuid } ?: return@launch\n            val newChapterTemp = currentChapter.copy(\n                readIndex = int,\n                isReadProgress = int != 0,\n                isReadFinish = int == (currentChapter.size - 1)\n            )\n            repository.updateLocalChapter(newChapterTemp)\n        }\n    }\n\n    private fun loadImp() {\n        loadJob = loadJop(Dispatchers.Default) {\n            list.forEach {\n                chapters[it.uuid] = it\n            }\n            loadHistory(initChapter.comicPathWord)\n            val mode = detectReaderMode()\n            readerModel.emit(mode)\n            chapterLoader.loadSingleChapter(initChapter.comicPathWord, state.value.uuid)\n            onInfoChange()\n            mangaContent.emit(ReaderContent(chapterLoader.snapshot(), state.value))\n        }\n    }\n\n    /**\n     * 检测漫画模式\n     */\n    private suspend fun detectReaderMode(): ReaderMode {\n        val modeId = repository.getHistoryByMangaPathWord(\n            currentPathWord\n        )?.readerModeId\n        return ReaderMode.idOf(modeId) ?: ReaderMode.valueOf(settingPref.readerMode)\n    }\n\n    private fun loadJop(\n        context: CoroutineContext = EmptyCoroutineContext,\n        start: CoroutineStart = CoroutineStart.DEFAULT,\n        block: suspend CoroutineScope.() -> Unit,\n    ) = viewModelScope.launch(context + createErrorHandler(), start) {\n        _loadingCounter.emit(true)\n        try {\n            block()\n        } finally {\n            _loadingCounter.emit(false)\n        }\n    }\n\n    private fun createErrorHandler() = CoroutineExceptionHandler { _, throwable ->\n        throwable.printStackTrace()\n        if (throwable !is CancellationException) {\n            _errorHandler.tryEmit(throwable)\n        }\n    }\n\n\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/RootViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.json.UpdateMetaDataJson\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass RootViewModel @Inject constructor(\n    private val updateMetaDataJson: UpdateMetaDataJson,\n) : ViewModel() {\n\n    val updateData = updateMetaDataJson.availableUpdateVersion()\n\n    init {\n        viewModelScope.launch {\n            updateMetaDataJson.fetchUpdate()\n        }\n    }\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/SearchResultViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.PagingData\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.data.search.SearchResultDataModel\nimport com.shicheeng.copymanga.resposity.MangaSearchRepository\nimport com.shicheeng.copymanga.resposity.logD\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.flatMapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass SearchResultViewModel @Inject constructor(\n    private val repository: MangaSearchRepository,\n) : ViewModel() {\n\n    private val mutableQueryString = MutableStateFlow(\"\")\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val searchResult: Flow<PagingData<SearchResultDataModel>> = mutableQueryString.flatMapLatest {\n        repository.fetchSearchResult(it)\n    }.cachedIn(viewModelScope)\n\n\n    fun loadSearch(word: String) = viewModelScope.launch {\n        mutableQueryString.emit(word)\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/SearchViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.data.searchhistory.SearchHistory\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.ExperimentalCoroutinesApi\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.combine\nimport kotlinx.coroutines.flow.mapLatest\nimport kotlinx.coroutines.flow.stateIn\nimport kotlinx.coroutines.launch\nimport javax.inject.Inject\n\n@HiltViewModel\nclass SearchViewModel @Inject constructor(\n    private val historyRepository: MangaHistoryRepository,\n) : ViewModel() {\n\n    private var _searchWord = MutableStateFlow(\"\")\n\n    @OptIn(ExperimentalCoroutinesApi::class)\n    val searchedHistoryWord = combine(\n        _searchWord,\n        historyRepository.historySearchedWord()\n    ) { s, list ->\n        if (s.isBlank()) {\n            list\n        } else {\n            list.filter { x -> x.word.contains(s) }\n        }\n    }.mapLatest {\n        it.map { x -> x.word }\n    }.stateIn(\n        scope = viewModelScope,\n        started = SharingStarted.Eagerly,\n        initialValue = emptyList()\n    )\n\n    fun upWord(wd: String) {\n        _searchWord.tryEmit(wd)\n    }\n\n\n    fun saveSearchWord(word: String) = viewModelScope.launch {\n        historyRepository.upsertSearchWord(\n            SearchHistory(\n                word = word,\n                time = System.currentTimeMillis()\n            )\n        )\n    }\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/SubscribedViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport com.shicheeng.copymanga.resposity.MangaHistoryRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport kotlinx.coroutines.flow.SharingStarted\nimport kotlinx.coroutines.flow.map\nimport kotlinx.coroutines.flow.stateIn\nimport javax.inject.Inject\n\n@HiltViewModel\nclass SubscribedViewModel @Inject constructor(\n    private val repository: MangaHistoryRepository,\n) : ViewModel() {\n\n    val data = repository.allHistoryDao.map { mangaHistoryDataModels ->\n        mangaHistoryDataModels.filter { it.isSubscribe }\n    }.stateIn(\n        scope = viewModelScope,\n        started = SharingStarted.Eagerly,\n        initialValue = emptyList()\n    )\n\n}"
  },
  {
    "path": "app/src/main/java/com/shicheeng/copymanga/viewmodel/WebShelfViewModel.kt",
    "content": "package com.shicheeng.copymanga.viewmodel\n\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.viewModelScope\nimport androidx.paging.cachedIn\nimport com.shicheeng.copymanga.resposity.WebShelfRepository\nimport dagger.hilt.android.lifecycle.HiltViewModel\nimport javax.inject.Inject\n\n@HiltViewModel\nclass WebShelfViewModel @Inject constructor(\n    webShelfRepository: WebShelfRepository,\n) : ViewModel() {\n\n    val data = webShelfRepository\n        .loadWebShelf()\n        .cachedIn(\n            scope = viewModelScope\n        )\n\n}"
  },
  {
    "path": "app/src/main/res/drawable/apache_svgrepo_com.xml",
    "content": "<vector android:height=\"24dp\" android:viewportHeight=\"32\"\n    android:viewportWidth=\"32\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#000000\" android:pathData=\"M10.039,18.947c-0.129,0.598 -0.233,1.321 -0.289,2.058l-0.003,0.056c0,0.025 -0.005,0.05 -0.006,0.075 -0.353,-0.444 -0.778,-0.812 -1.261,-1.093l-0.021,-0.011c0.634,0.802 1.079,1.781 1.251,2.851l0.005,0.036c-0.074,0.007 -0.159,0.011 -0.246,0.011 -0.427,0 -0.832,-0.094 -1.196,-0.262l0.018,0.007c0.327,0.335 0.735,0.588 1.192,0.729l0.02,0.005c-0.654,0.131 -1.224,0.426 -1.685,0.84l0.003,-0.003c0.47,-0.241 1.025,-0.383 1.613,-0.383 0.134,0 0.267,0.007 0.397,0.022l-0.016,-0.001c-0.762,2.174 -1.537,4.567 -2.303,7.11 0.217,-0.064 0.385,-0.228 0.453,-0.438l0.001,-0.005c0.137,-0.46 1.05,-3.482 2.472,-7.454l0.156,-0.435c0.15,-0.415 0.307,-0.84 0.467,-1.275l0.112,-0.296v-0.005l-1.122,-2.213c-0.004,0.025 -0.012,0.05 -0.015,0.075zM11.759,19.541c0.197,-0.507 0.399,-1.012 0.604,-1.531 0.195,-0.492 0.4,-0.987 0.605,-1.487q0.951,-2.273 1.999,-4.504l0.256,-0.53c0.15,-0.304 0.296,-0.606 0.45,-0.905 0.006,-0.019 0.014,-0.036 0.025,-0.05l-0,0 -1.118,-2.203 -0.055,0.087c-0.259,0.425 -0.517,0.858 -0.771,1.302q-0.721,1.254 -1.365,2.549l-0.117,0.241c-0.531,1.05 -1.063,2.326 -1.508,3.641l-0.064,0.216c-0.222,0.654 -0.447,1.491 -0.624,2.346l-0.026,0.15 1.12,2.212c0.146,-0.396 0.3,-0.797 0.455,-1.203zM16.42,9.144q0.77,-1.438 1.632,-2.824l0.05,-0.08c0.28,-0.44 0.562,-0.866 0.846,-1.275l-0.856,-1.616 -0.196,0.24c-0.246,0.306 -0.504,0.637 -0.766,0.987q-1.343,1.798 -2.519,3.711l-0.028,0.047 1.116,2.203c0.237,-0.472 0.475,-0.94 0.719,-1.397zM20.274,1.144c-0.834,0.636 -1.554,1.362 -2.164,2.175l-0.02,0.028 0.857,1.617c0.594,-0.857 1.194,-1.605 1.841,-2.31l-0.014,0.016 0.072,-0.077c-0.025,0.024 -0.048,0.049 -0.07,0.076l-0.001,0.002c-0.598,0.69 -1.165,1.45 -1.672,2.251l-0.046,0.077c1.266,-0.092 2.408,-0.238 3.53,-0.442l-0.199,0.03c0.083,-0.285 0.131,-0.612 0.131,-0.95 0,-0.635 -0.168,-1.23 -0.462,-1.744l0.009,0.017s-0.825,-1.337 -1.794,-0.762zM11.339,21.561q-0.219,0.605 -0.444,1.24l-0.006,0.019c-0.02,0.057 -0.04,0.117 -0.062,0.177 -0.1,0.284 -0.187,0.54 -0.387,1.125 0.37,0.241 0.66,0.578 0.838,0.977l0.006,0.014c-0.025,-0.491 -0.244,-0.927 -0.581,-1.236l-0.001,-0.001c0.186,0.032 0.4,0.05 0.618,0.05 1.273,0 2.403,-0.613 3.111,-1.56l0.007,-0.01c0.054,-0.09 0.113,-0.199 0.165,-0.312l0.009,-0.023c-0.287,0.353 -0.722,0.577 -1.209,0.577 -0.103,0 -0.203,-0.01 -0.3,-0.029l0.01,0.002h-0.001c0.925,-0.348 1.679,-0.973 2.181,-1.773l0.011,-0.018c0.117,-0.191 0.232,-0.4 0.35,-0.629 -0.648,0.711 -1.577,1.155 -2.61,1.155 -0.255,0 -0.503,-0.027 -0.742,-0.078l0.023,0.004 -0.9,0.097q-0.044,0.114 -0.084,0.229zM15.868,10.727l-0.096,0.2c-0.097,0.2 -0.196,0.4 -0.295,0.61 -0.107,0.225 -0.215,0.455 -0.325,0.69l-0.165,0.359q-0.941,2.04 -1.783,4.124 -0.306,0.744 -0.616,1.537c-0.187,0.475 -0.371,0.956 -0.562,1.455l-0.025,0.075c-0.187,0.495 -0.375,1.002 -0.566,1.525l-0.012,0.034 0.9,-0.1c-0.019,-0.001 -0.037,-0.004 -0.054,-0.008l0.002,0c1.369,-0.283 2.546,-0.97 3.433,-1.929l0.004,-0.004c0.438,-0.478 0.827,-1.013 1.152,-1.589l0.022,-0.043c0.246,-0.428 0.499,-0.945 0.72,-1.478l0.035,-0.094c0.21,-0.506 0.41,-1.053 0.6,-1.647 -0.243,0.127 -0.524,0.229 -0.82,0.29l-0.021,0.004c-0.095,0.024 -0.211,0.044 -0.329,0.056l-0.012,0.001c0.945,-0.394 1.686,-1.118 2.093,-2.025l0.01,-0.025c-0.345,0.242 -0.75,0.426 -1.186,0.53l-0.024,0.005c-0.075,0.015 -0.145,0.027 -0.217,0.037l-0.054,0.008h0.003c0.343,-0.141 0.638,-0.31 0.908,-0.511l-0.011,0.008c0.317,-0.24 0.581,-0.53 0.788,-0.859l0.008,-0.013 0.079,-0.13 0.096,-0.192c0.146,-0.282 0.301,-0.632 0.436,-0.992l0.023,-0.07 0.038,-0.11c0.059,-0.161 0.112,-0.355 0.15,-0.555l0.004,-0.024c-0.034,0.028 -0.073,0.055 -0.113,0.079l-0.004,0.002c-0.36,0.193 -0.777,0.34 -1.218,0.421l-0.026,0.004 -0.001,-0.001h-0.021l-0.125,0.021 0.021,-0.01 -2.83,0.312 -0.016,0.027zM19.059,4.999c-0.255,0.387 -0.53,0.825 -0.825,1.325l-0.05,0.077q-0.832,1.407 -1.581,2.862 -0.351,0.675 -0.721,1.432l2.833,-0.312c0.639,-0.255 1.166,-0.676 1.545,-1.209l0.007,-0.011q0.147,-0.212 0.287,-0.427c0.287,-0.454 0.575,-0.953 0.829,-1.45 0.246,-0.482 0.462,-0.958 0.631,-1.387 0.104,-0.275 0.187,-0.527 0.247,-0.75 0.052,-0.197 0.092,-0.384 0.125,-0.562 -0.924,0.174 -2.066,0.32 -3.226,0.406l-0.108,0.006zM24.379,3.75l-0.219,0.441 -0.215,-0.441h-0.109v0.632h0.084v-0.504l0.215,0.437h0.056l0.215,-0.437v0.505h0.082v-0.632zM23.254,3.75v0.082h0.195v0.55h0.09v-0.55h0.195v-0.082z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_add_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_cached_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M19,8l-4,4h3c0,3.31 -2.69,6 -6,6 -1.01,0 -1.97,-0.25 -2.8,-0.7l-1.46,1.46C8.97,19.54 10.43,20 12,20c4.42,0 8,-3.58 8,-8h3l-4,-4zM6,12c0,-3.31 2.69,-6 6,-6 1.01,0 1.97,0.25 2.8,0.7l1.46,-1.46C15.03,4.46 13.57,4 12,4c-4.42,0 -8,3.58 -8,8H1l4,4 4,-4H6z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_close_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_comment_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M21.99,4c0,-1.1 -0.89,-2 -1.99,-2L4,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_content_cut_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M9.64,7.64c0.23,-0.5 0.36,-1.05 0.36,-1.64 0,-2.21 -1.79,-4 -4,-4S2,3.79 2,6s1.79,4 4,4c0.59,0 1.14,-0.13 1.64,-0.36L10,12l-2.36,2.36C7.14,14.13 6.59,14 6,14c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4c0,-0.59 -0.13,-1.14 -0.36,-1.64L12,14l7,7h3v-1L9.64,7.64zM6,8c-1.1,0 -2,-0.89 -2,-2s0.9,-2 2,-2 2,0.89 2,2 -0.9,2 -2,2zM6,20c-1.1,0 -2,-0.89 -2,-2s0.9,-2 2,-2 2,0.89 2,2 -0.9,2 -2,2zM12,12.5c-0.28,0 -0.5,-0.22 -0.5,-0.5s0.22,-0.5 0.5,-0.5 0.5,0.22 0.5,0.5 -0.22,0.5 -0.5,0.5zM19,3l-6,6 2,2 7,-7L22,3z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_delete_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_delete_outline_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8,9h8v10L8,19L8,9zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_done_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_explore_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,10.9c-0.61,0 -1.1,0.49 -1.1,1.1s0.49,1.1 1.1,1.1c0.61,0 1.1,-0.49 1.1,-1.1s-0.49,-1.1 -1.1,-1.1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM14.19,14.19L6,18l3.81,-8.19L18,6l-3.81,8.19z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_format_list_bulleted_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:autoMirrored=\"true\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M4,10.5c-0.83,0 -1.5,0.67 -1.5,1.5s0.67,1.5 1.5,1.5 1.5,-0.67 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM4,4.5c-0.83,0 -1.5,0.67 -1.5,1.5S3.17,7.5 4,7.5 5.5,6.83 5.5,6 4.83,4.5 4,4.5zM4,16.5c-0.83,0 -1.5,0.68 -1.5,1.5s0.68,1.5 1.5,1.5 1.5,-0.68 1.5,-1.5 -0.67,-1.5 -1.5,-1.5zM7,19h14v-2L7,17v2zM7,13h14v-2L7,11v2zM7,5v2h14L21,5L7,5z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_history_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_insert_chart_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM9,17L7,17v-7h2v7zM13,17h-2L11,7h2v10zM17,17h-2v-4h2v4z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_insert_chart_outlined_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M9,17L7,17v-7h2v7zM13,17h-2L11,7h2v10zM17,17h-2v-4h2v4zM19.5,19.1h-15L4.5,5h15v14.1zM19.5,3h-15c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h15c1.1,0 2,-0.9 2,-2L21.5,5c0,-1.1 -0.9,-2 -2,-2z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_library_add_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM19,11h-4v4h-2v-4L9,11L9,9h4L13,5h2v4h4v2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_library_add_check_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12.47,14L9,10.5l1.4,-1.41 2.07,2.08L17.6,6 19,7.41 12.47,14zM4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_pause_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_person_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_play_arrow_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M8,5v14l11,-7z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_remove_done_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M1.79,12l5.58,5.59L5.96,19 0.37,13.41 1.79,12zM2.24,4.22L12.9,14.89l-1.28,1.28L7.44,12l-1.41,1.41L11.62,19l2.69,-2.69 4.89,4.89 1.41,-1.41L3.65,2.81 2.24,4.22zM17.14,13.49L23.62,7 22.2,5.59l-6.48,6.48 1.42,1.42zM17.96,7l-1.41,-1.41 -3.65,3.66 1.41,1.41L17.96,7z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_replay_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,5V1L7,6l5,5V7c3.31,0 6,2.69 6,6s-2.69,6 -6,6 -6,-2.69 -6,-6H4c0,4.42 3.58,8 8,8s8,-3.58 8,-8 -3.58,-8 -8,-8z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_rss_feed_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6.18,17.82m-2.18,0a2.18,2.18 0,1 1,4.36 0a2.18,2.18 0,1 1,-4.36 0\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M4,4.44v2.83c7.03,0 12.73,5.7 12.73,12.73h2.83c0,-8.59 -6.97,-15.56 -15.56,-15.56zM4,10.1v2.83c3.9,0 7.07,3.17 7.07,7.07h2.83c0,-5.47 -4.43,-9.9 -9.9,-9.9z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_security_update_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3c0,-1.1 -0.9,-2 -2,-2H7C5.9,1 5,1.9 5,3zM17,18H7V6h10V18zM16,12h-3V8h-2v4H8l4,4L16,12z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_send_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_visibility_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_visibility_off_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,7c2.76,0 5,2.24 5,5 0,0.65 -0.13,1.26 -0.36,1.83l2.92,2.92c1.51,-1.26 2.7,-2.89 3.43,-4.75 -1.73,-4.39 -6,-7.5 -11,-7.5 -1.4,0 -2.74,0.25 -3.98,0.7l2.16,2.16C10.74,7.13 11.35,7 12,7zM2,4.27l2.28,2.28 0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5 1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22 21,20.73 3.27,3 2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.66 1.34,3 3,3 0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53 -2.76,0 -5,-2.24 -5,-5 0,-0.79 0.2,-1.53 0.53,-2.2zM11.84,9.02l3.15,3.15 0.02,-0.16c0,-1.66 -1.34,-3 -3,-3l-0.17,0.01z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_warning_amber_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,5.99L19.53,19H4.47L12,5.99M12,2L1,21h22L12,2L12,2z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M13,16l-2,0l0,2l2,0z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M13,10l-2,0l0,5l2,0z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/baseline_webhook_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M10,15l5.88,0c0.27,-0.31 0.67,-0.5 1.12,-0.5c0.83,0 1.5,0.67 1.5,1.5c0,0.83 -0.67,1.5 -1.5,1.5c-0.44,0 -0.84,-0.19 -1.12,-0.5l-3.98,0c-0.46,2.28 -2.48,4 -4.9,4c-2.76,0 -5,-2.24 -5,-5c0,-2.42 1.72,-4.44 4,-4.9l0,2.07C4.84,13.58 4,14.7 4,16c0,1.65 1.35,3 3,3s3,-1.35 3,-3V15zM12.5,4c1.65,0 3,1.35 3,3h2c0,-2.76 -2.24,-5 -5,-5l0,0c-2.76,0 -5,2.24 -5,5c0,1.43 0.6,2.71 1.55,3.62l-2.35,3.9C6.02,14.66 5.5,15.27 5.5,16c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5c0,-0.16 -0.02,-0.31 -0.07,-0.45l3.38,-5.63C10.49,9.61 9.5,8.42 9.5,7C9.5,5.35 10.85,4 12.5,4zM17,13c-0.64,0 -1.23,0.2 -1.72,0.54l-3.05,-5.07C11.53,8.35 11,7.74 11,7c0,-0.83 0.67,-1.5 1.5,-1.5S14,6.17 14,7c0,0.15 -0.02,0.29 -0.06,0.43l2.19,3.65C16.41,11.03 16.7,11 17,11l0,0c2.76,0 5,2.24 5,5c0,2.76 -2.24,5 -5,5c-1.85,0 -3.47,-1.01 -4.33,-2.5l2.67,0C15.82,18.82 16.39,19 17,19c1.65,0 3,-1.35 3,-3S18.65,13 17,13z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_arrow_avd.xml",
    "content": "<animated-vector\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\">\n    <aapt:attr name=\"android:drawable\">\n        <vector\n            android:name=\"vector\"\n            android:width=\"24dp\"\n            android:height=\"24dp\"\n            android:tint=\"?colorControlNormal\"\n            android:viewportWidth=\"24\"\n            android:viewportHeight=\"24\">\n            <group\n                android:name=\"group\"\n                android:pivotX=\"12\"\n                android:pivotY=\"12\">\n                <path\n                    android:name=\"path\"\n                    android:pathData=\"M 7.41 15.41 L 12 10.83 L 16.59 15.41 L 18 14 L 12 8 L 6 14 Z\"\n                    android:fillColor=\"#000000\"/>\n            </group>\n        </vector>\n    </aapt:attr>\n    <target android:name=\"group\">\n        <aapt:attr name=\"android:animation\">\n            <objectAnimator\n                android:propertyName=\"rotation\"\n                android:duration=\"500\"\n                android:valueFrom=\"0\"\n                android:valueTo=\"180\"\n                android:valueType=\"floatType\"\n                android:interpolator=\"@android:anim/linear_interpolator\"/>\n        </aapt:attr>\n    </target>\n</animated-vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_home_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_hot.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M13.5,0.67s0.74,2.65 0.74,4.8c0,2.06 -1.35,3.73 -3.41,3.73 -2.07,0 -3.63,-1.67 -3.63,-3.73l0.03,-0.36C5.21,7.51 4,10.62 4,14c0,4.42 3.58,8 8,8s8,-3.58 8,-8C20,8.61 17.41,3.8 13.5,0.67zM11.71,19c-1.78,0 -3.22,-1.4 -3.22,-3.14 0,-1.62 1.05,-2.76 2.81,-3.12 1.77,-0.36 3.6,-1.21 4.62,-2.58 0.39,1.29 0.59,2.65 0.59,4.04 0,2.65 -2.15,4.8 -4.8,4.8z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_loop.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_baseline_region.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_done_all.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M18,7l-1.41,-1.41 -6.34,6.34 1.41,1.41L18,7zM22.24,5.59L11.66,16.17 7.48,12l-1.41,1.41L11.66,19l12,-12 -1.42,-1.41zM0.41,13.41L6,19l1.41,-1.41L1.83,12 0.41,13.41z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_home_selector.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<animated-selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <item\n        android:id=\"@+id/normal\"\n        android:drawable=\"@drawable/ic_outline_home_24\"\n        android:state_checked=\"false\" />\n\n    <item\n        android:id=\"@+id/checked\"\n        android:drawable=\"@drawable/ic_baseline_home_24\"\n        android:state_checked=\"true\" />\n\n    <transition\n        android:drawable=\"@drawable/ic_baseline_home_24\"\n        android:fromId=\"@id/normal\"\n        android:toId=\"@id/checked\" />\n\n    <transition\n        android:drawable=\"@drawable/ic_outline_home_24\"\n        android:fromId=\"@id/checked\"\n        android:toId=\"@id/normal\" />\n\n</animated-selector>"
  },
  {
    "path": "app/src/main/res/drawable/ic_outline_home_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:strokeColor=\"@android:color/white\"\n        android:strokeWidth=\"1\"\n        android:pathData=\"M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_outline_page.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M22.47,5.2C22,4.96 21.51,4.76 21,4.59v12.03C19.86,16.21 18.69,16 17.5,16c-1.9,0 -3.78,0.54 -5.5,1.58V5.48C10.38,4.55 8.51,4 6.5,4C4.71,4 3.02,4.44 1.53,5.2C1.2,5.36 1,5.71 1,6.08v12.08c0,0.58 0.47,0.99 1,0.99c0.16,0 0.32,-0.04 0.48,-0.12C3.69,18.4 5.05,18 6.5,18c2.07,0 3.98,0.82 5.5,2c1.52,-1.18 3.43,-2 5.5,-2c1.45,0 2.81,0.4 4.02,1.04c0.16,0.08 0.32,0.12 0.48,0.12c0.52,0 1,-0.41 1,-0.99V6.08C23,5.71 22.8,5.36 22.47,5.2zM10,16.62C8.86,16.21 7.69,16 6.5,16c-1.19,0 -2.36,0.21 -3.5,0.62V6.71C4.11,6.24 5.28,6 6.5,6C7.7,6 8.89,6.25 10,6.72V16.62zM19,0.5l-5,5V15l5,-4.5V0.5z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_skip_next_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_skip_previous_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/iconmonstr_github_5.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n  <path\n      android:fillColor=\"#FF000000\"\n      android:pathData=\"m12,3.74878c4.54972,0 8.25122,3.7015 8.25122,8.25122s-3.7015,8.25122 -8.25122,8.25122s-8.25122,-3.7015 -8.25122,-8.25122s3.7015,-8.25122 8.25122,-8.25122zm0,-1.65024c-5.46808,0 -9.90146,4.43338 -9.90146,9.90146s4.43338,9.90146 9.90146,9.90146s9.90146,-4.43338 9.90146,-9.90146s-4.43338,-9.90146 -9.90146,-9.90146zm0,4.95073c-2.73363,0 -4.95073,2.21628 -4.95073,4.95073c0,2.1874 1.41838,4.0431 3.3863,4.69742c0.24754,0.04621 0.32675,-0.10727 0.32675,-0.23846l0,-0.92166c-1.37713,0.29952 -1.66427,-0.58336 -1.66427,-0.58336c-0.22443,-0.57181 -0.54953,-0.72446 -0.54953,-0.72446c-0.44887,-0.30777 0.03383,-0.30117 0.03383,-0.30117c0.49755,0.03466 0.75911,0.51075 0.75911,0.51075c0.44144,0.75664 1.15765,0.53798 1.44066,0.41174c0.04456,-0.32015 0.17245,-0.53798 0.31437,-0.66175c-1.09989,-0.12542 -2.25506,-0.55036 -2.25506,-2.44649c0,-0.54045 0.19308,-0.98189 0.50993,-1.32845c-0.05116,-0.12624 -0.22113,-0.63039 0.04786,-1.31194c0,0 0.41586,-0.13284 1.36145,0.50745c0.39523,-0.10974 0.81852,-0.1642 1.23933,-0.16667c0.42081,0.00165 0.8441,0.05693 1.24016,0.16667c0.94559,-0.64029 1.3598,-0.50745 1.3598,-0.50745c0.26981,0.68155 0.09984,1.1857 0.04951,1.31029c0.31767,0.34655 0.5091,0.78799 0.5091,1.32845c0,1.90191 -1.15847,2.32024 -2.26083,2.44236c0.17823,0.15347 0.33995,0.45464 0.33995,0.91671l0,1.35815c0,0.13202 0.07921,0.28632 0.33005,0.23764c1.96627,-0.65432 3.383,-2.5092 3.383,-4.69577c0,-2.73445 -2.2171,-4.95073 -4.95073,-4.95073z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/iconmonstr_rss_feed_baseline.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"#FF000000\"\n        android:pathData=\"m12,2.28545c-5.36486,0 -9.71455,4.34969 -9.71455,9.71455s4.34969,9.71455 9.71455,9.71455s9.71455,-4.34969 9.71455,-9.71455s-4.34969,-9.71455 -9.71455,-9.71455zm-2.73141,13.76228c-0.72616,0 -1.31632,-0.58854 -1.31632,-1.3147s0.59016,-1.3147 1.31632,-1.3147s1.31632,0.58854 1.31632,1.3147s-0.59016,1.3147 -1.31632,1.3147zm3.14509,0c-0.02429,-2.44645 -2.01172,-4.43146 -4.46141,-4.45574l0,-1.94777c3.53043,0.02429 6.38651,2.87794 6.4116,6.40351l-1.9502,0zm3.30376,0c-0.01295,-4.28817 -3.48348,-7.74817 -7.76517,-7.76678l0,-1.94777c5.36162,0.01862 9.70241,4.3586 9.71455,9.71455l-1.94939,0z\" />\n</vector>"
  },
  {
    "path": "app/src/main/res/drawable/iconmonstr_rss_feed_outline.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n  <path\n      android:fillColor=\"#FF000000\"\n      android:pathData=\"m12,3.53846c4.66569,0 8.46154,3.79585 8.46154,8.46154s-3.79585,8.46154 -8.46154,8.46154s-8.46154,-3.79585 -8.46154,-8.46154s3.79585,-8.46154 8.46154,-8.46154zm0,-1.69231c-5.60746,0 -10.15385,4.54638 -10.15385,10.15385s4.54638,10.15385 10.15385,10.15385s10.15385,-4.54638 10.15385,-10.15385s-4.54638,-10.15385 -10.15385,-10.15385zm-1.09154,12.39277c0,0.63292 -0.51362,1.14569 -1.14569,1.14569c-0.63377,0 -1.14738,-0.51277 -1.14738,-1.14569c0,-0.63208 0.51362,-1.14485 1.14654,-1.14485c0.63292,0.00085 1.14654,0.51277 1.14654,1.14485zm-2.29308,-4.43131l0,1.69569c2.13315,0.02115 3.86438,1.74985 3.88554,3.88131l1.69908,0c-0.022,-3.07069 -2.50885,-5.55585 -5.58462,-5.577zm0,-1.188c3.729,0.01692 6.75231,3.03008 6.76331,6.765l1.69823,0c-0.01015,-4.66485 -3.79077,-8.44546 -8.46154,-8.46154l0,1.69654z\"/>\n\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/legal_license_mit_svgrepo_com.xml",
    "content": "<vector android:height=\"24dp\" android:viewportHeight=\"14\"\n    android:viewportWidth=\"14\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#000000\" android:pathData=\"m2.178,10.266 l0,-0.991 0.134,0 0.134,0 0,0.884 0,0.884 0.482,0c0.446,0 0.482,0.01 0.482,0.107 0,0.101 -0.036,0.107 -0.616,0.107l-0.616,0 0,-0.991zM3.731,10.507c0,-0.714 0.005,-0.75 0.107,-0.75 0.102,0 0.107,0.036 0.107,0.75 0,0.714 -0.005,0.75 -0.107,0.75 -0.102,0 -0.107,-0.036 -0.107,-0.75zM4.509,11.129c-0.274,-0.274 -0.298,-0.912 -0.045,-1.213 0.141,-0.167 0.408,-0.247 0.637,-0.189 0.166,0.042 0.397,0.261 0.397,0.376 0,0.132 -0.234,0.102 -0.295,-0.038C5.147,9.937 4.98,9.888 4.776,9.939c-0.34,0.085 -0.302,1.045 0.045,1.132 0.156,0.039 0.331,-0.043 0.411,-0.191 0.068,-0.127 0.267,-0.143 0.267,-0.021 0,0.046 -0.07,0.155 -0.157,0.241 -0.132,0.132 -0.199,0.156 -0.431,0.156 -0.218,0 -0.301,-0.026 -0.402,-0.128zM5.928,11.105c-0.281,-0.281 -0.282,-0.89 -0.002,-1.203 0.137,-0.154 0.184,-0.172 0.447,-0.172 0.218,0 0.324,0.028 0.413,0.107 0.143,0.127 0.266,0.399 0.266,0.587l0,0.136 -0.542,0 -0.542,0 0.034,0.174c0.065,0.338 0.419,0.468 0.691,0.254 0.167,-0.131 0.332,-0.144 0.286,-0.022 -0.018,0.047 -0.032,0.094 -0.032,0.106 0,0.072 -0.359,0.184 -0.591,0.184 -0.23,0 -0.299,-0.025 -0.427,-0.152zM6.784,10.289c0,-0.081 -0.112,-0.283 -0.182,-0.33 -0.032,-0.022 -0.131,-0.039 -0.22,-0.039 -0.19,0 -0.257,0.039 -0.34,0.196 -0.11,0.21 -0.079,0.231 0.34,0.231 0.249,0 0.402,-0.022 0.402,-0.057zM7.373,10.507c0,-0.714 0.005,-0.75 0.107,-0.75 0.073,0 0.107,0.036 0.107,0.112 0,0.108 0.006,0.107 0.165,-0.027 0.218,-0.183 0.489,-0.186 0.668,-0.01 0.125,0.125 0.131,0.163 0.131,0.777 0,0.609 -0.006,0.645 -0.107,0.645 -0.1,0 -0.107,-0.036 -0.107,-0.532 0,-0.7 -0.041,-0.807 -0.312,-0.807 -0.334,0 -0.398,0.115 -0.427,0.777 -0.022,0.504 -0.035,0.562 -0.125,0.562 -0.093,0 -0.1,-0.053 -0.1,-0.75zM9.053,11.194c-0.063,-0.031 -0.141,-0.113 -0.173,-0.184 -0.051,-0.112 -0.045,-0.128 0.047,-0.128 0.058,0 0.154,0.048 0.213,0.107 0.07,0.07 0.179,0.107 0.311,0.107 0.261,0 0.401,-0.1 0.377,-0.271 -0.015,-0.103 -0.069,-0.146 -0.259,-0.201 -0.416,-0.121 -0.59,-0.219 -0.644,-0.363 -0.167,-0.44 0.564,-0.725 0.993,-0.387 0.156,0.123 0.167,0.18 0.045,0.227 -0.054,0.021 -0.128,-0.01 -0.19,-0.075 -0.121,-0.13 -0.479,-0.149 -0.577,-0.031 -0.129,0.155 -0.039,0.258 0.33,0.378 0.455,0.148 0.525,0.207 0.524,0.448 -0.001,0.224 -0.035,0.289 -0.197,0.374 -0.143,0.075 -0.644,0.075 -0.801,0zM10.598,11.173c-0.271,-0.19 -0.367,-0.728 -0.201,-1.125 0.15,-0.359 0.747,-0.454 1.035,-0.165 0.124,0.124 0.251,0.581 0.181,0.651 -0.015,0.015 -0.252,0.027 -0.527,0.027 -0.5,0 -0.5,0 -0.5,0.136 0,0.325 0.468,0.521 0.696,0.292 0.059,-0.059 0.143,-0.107 0.187,-0.107 0.127,0 0.094,0.142 -0.061,0.264 -0.175,0.138 -0.632,0.153 -0.811,0.027zM11.369,10.262c-0.018,-0.047 -0.032,-0.105 -0.032,-0.13 0,-0.109 -0.183,-0.214 -0.376,-0.214 -0.219,0 -0.374,0.138 -0.374,0.333 0,0.083 0.053,0.095 0.407,0.095 0.35,0 0.403,-0.012 0.375,-0.085zM3.731,9.302c0,-0.098 0.029,-0.134 0.107,-0.134 0.079,0 0.107,0.036 0.107,0.134 0,0.098 -0.029,0.134 -0.107,0.134 -0.079,0 -0.107,-0.036 -0.107,-0.134zM1.643,8.231 L1.643,7.936 1.321,7.936 1,7.936 1,7.642 1,7.347 1.321,7.347 1.643,7.347 1.643,7.053 1.643,6.758 1.321,6.758 1,6.758 1,4.75 1,2.741 3.544,2.741 6.088,2.741 6.088,4.747 6.088,6.753 5.78,6.769 5.472,6.785 5.456,7.066 5.439,7.347 5.764,7.347 6.088,7.347 6.088,7.642 6.088,7.936 5.766,7.936 5.445,7.936 5.445,8.231 5.445,8.525 5.124,8.525 4.802,8.525 4.802,8.231 4.802,7.936 5.124,7.936 5.445,7.936 5.445,7.642 5.445,7.347 5.121,7.347 4.797,7.347 4.813,7.066 4.829,6.785 5.137,6.769 5.445,6.753 5.445,6.49 5.445,6.228 5.137,6.212 4.829,6.196 4.815,5.111 4.8,4.027 4.426,4.027 4.053,4.027 4.053,6.276 4.053,8.526 3.571,8.526 3.089,8.526 3.089,6.276 3.089,4.027 2.687,4.027 2.285,4.027 2.285,5.125 2.285,6.223 1.964,6.223 1.643,6.223 1.643,6.491 1.643,6.758 1.964,6.758 2.285,6.758 2.285,7.053 2.285,7.347 1.964,7.347 1.643,7.347 1.643,7.642 1.643,7.937 1.964,7.937 2.285,7.937 2.285,8.231 2.285,8.526 1.964,8.526 1.643,8.526 1.643,8.231zM6.838,5.633 L6.838,2.741 7.48,2.741 8.123,2.741 8.123,5.633 8.123,8.525 7.48,8.525 6.838,8.525 6.838,5.633zM10.908,8.231 L10.908,7.936 10.613,7.936 10.319,7.936 10.319,7.642 10.319,7.347 10.613,7.347 10.908,7.347 10.908,7.053 10.908,6.758 10.6,6.758 10.292,6.758 10.307,5.392 10.322,4.027 9.598,4.027 8.873,4.027 8.873,3.384 8.873,2.741 10.936,2.741 13,2.741 12.985,3.371 12.97,4 12.26,4.015 11.551,4.03 11.551,5.126 11.551,6.223 11.226,6.223 10.902,6.223 10.918,6.477 10.935,6.731 11.243,6.747 11.551,6.763 11.551,7.053 11.551,7.342 11.243,7.358 10.935,7.374 10.935,7.642 10.935,7.909 11.243,7.925 11.551,7.941 11.551,8.233 11.551,8.525 11.229,8.525 10.908,8.525 10.908,8.231z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/open_source_fill_svgrepo_com.xml",
    "content": "<vector android:height=\"24dp\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#FF000000\" android:pathData=\"M12,2c5.523,0 10,4.477 10,10 0,4.13 -2.504,7.676 -6.077,9.201l-2.518,-6.55C14.354,14.148 15,13.15 15,12c0,-1.657 -1.343,-3 -3,-3s-3,1.343 -3,3c0,1.15 0.647,2.148 1.596,2.652l-2.518,6.55C4.504,19.675 2,16.13 2,12 2,6.477 6.477,2 12,2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_auto_mode_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M19.03,3.56c-1.67,-1.39 -3.74,-2.3 -6.03,-2.51v2.01c1.73,0.19 3.31,0.88 4.61,1.92L19.03,3.56z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M11,3.06V1.05C8.71,1.25 6.64,2.17 4.97,3.56l1.42,1.42C7.69,3.94 9.27,3.25 11,3.06z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M4.98,6.39L3.56,4.97C2.17,6.64 1.26,8.71 1.05,11h2.01C3.25,9.27 3.94,7.69 4.98,6.39z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M20.94,11h2.01c-0.21,-2.29 -1.12,-4.36 -2.51,-6.03l-1.42,1.42C20.06,7.69 20.75,9.27 20.94,11z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M7,12l3.44,1.56l1.56,3.44l1.56,-3.44l3.44,-1.56l-3.44,-1.56l-1.56,-3.44l-1.56,3.44z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,21c-3.11,0 -5.85,-1.59 -7.46,-4H7v-2H1v6h2v-2.7c1.99,2.84 5.27,4.7 9,4.7c4.87,0 9,-3.17 10.44,-7.56l-1.96,-0.45C19.25,18.48 15.92,21 12,21z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_cell_wifi_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M6,22h16V5.97L6,22zM20,20h-2v-7.22l2,-2V20zM5.22,7.22L3.93,5.93c3.9,-3.91 10.24,-3.91 14.15,0l-1.29,1.29C13.6,4.03 8.41,4.03 5.22,7.22zM12.93,11.07L11,13l-1.93,-1.93C10.14,10.01 11.86,10.01 12.93,11.07zM14.22,9.79c-1.78,-1.77 -4.66,-1.77 -6.43,0L6.5,8.5c2.48,-2.48 6.52,-2.48 9,0L14.22,9.79z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_chrome_reader_mode_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M21,4L3,4c-1.1,0 -2,0.9 -2,2v13c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,6c0,-1.1 -0.9,-2 -2,-2zM3,19L3,6h8v13L3,19zM21,19h-8L13,6h8v13zM14,9.5h6L20,11h-6zM14,12h6v1.5h-6zM14,14.5h6L20,16h-6z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_clean_hands_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M16.99,5l0.63,1.37L18.99,7l-1.37,0.63L16.99,9l-0.63,-1.37L14.99,7l1.37,-0.63L16.99,5M20,14c1.1,0 2,-0.9 2,-2c0,-1.1 -2,-4 -2,-4s-2,2.9 -2,4C18,13.1 18.9,14 20,14zM11,6.1V4h2c0.57,0 1.1,0.17 1.55,0.45l1.43,-1.43C15.15,2.39 14.13,2 13,2c-1.47,0 -5.44,0 -5.5,0v2H9v2.11C7.22,6.48 5.8,7.79 5.25,9.5h2.16C7.94,8.61 8.89,8 10,8c1.62,0 2.94,1.29 2.99,2.9L15,11.65V11C15,8.58 13.28,6.56 11,6.1zM22,19v1l-8,2.5l-7,-1.94V22H1V11h7.97l6.16,2.3C16.25,13.72 17,14.8 17,16h2C20.66,16 22,17.34 22,19zM5,20v-7H3v7H5zM19.9,18.57c-0.16,-0.33 -0.51,-0.56 -0.9,-0.56h-5.35c-0.54,0 -1.07,-0.09 -1.58,-0.26l-2.38,-0.79l0.63,-1.9l2.38,0.79C13.01,15.95 15,16 15,16c0,-0.37 -0.23,-0.7 -0.57,-0.83L8.61,13H7v5.48l6.97,1.93L19.9,18.57z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_cleaning_services_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M16,11h-1V3c0,-1.1 -0.9,-2 -2,-2h-2C9.9,1 9,1.9 9,3v8H8c-2.76,0 -5,2.24 -5,5v7h18v-7C21,13.24 18.76,11 16,11zM11,3h2v8h-2V3zM19,21h-2v-3c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v3h-2v-3c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v3H9v-3c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v3H5v-5c0,-1.65 1.35,-3 3,-3h8c1.65,0 3,1.35 3,3V21z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_cloud_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,6c2.62,0 4.88,1.86 5.39,4.43l0.3,1.5 1.53,0.11c1.56,0.1 2.78,1.41 2.78,2.96 0,1.65 -1.35,3 -3,3H6c-2.21,0 -4,-1.79 -4,-4 0,-2.05 1.53,-3.76 3.56,-3.97l1.07,-0.11 0.5,-0.95C8.08,7.14 9.94,6 12,6m0,-2C9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96C18.67,6.59 15.64,4 12,4z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_comment_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M21.99,4c0,-1.1 -0.89,-2 -1.99,-2L4,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h14l4,4 -0.01,-18zM20,4v13.17L18.83,16L4,16L4,4h16zM6,12h12v2L6,14zM6,9h12v2L6,11zM6,6h12v2L6,8z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_contrast_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,22c5.52,0 10,-4.48 10,-10S17.52,2 12,2S2,6.48 2,12S6.48,22 12,22zM13,4.07c3.94,0.49 7,3.85 7,7.93s-3.05,7.44 -7,7.93V4.07z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_do_not_disturb_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10s10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8c0,-1.85 0.63,-3.55 1.69,-4.9L16.9,18.31C15.55,19.37 13.85,20 12,20zM18.31,16.9L7.1,5.69C8.45,4.63 10.15,4 12,4c4.42,0 8,3.58 8,8C20,13.85 19.37,15.55 18.31,16.9z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_download_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M19,9h-4L15,3L9,3v6L5,9l7,7 7,-7zM11,11L11,5h2v6h1.17L12,13.17 9.83,11L11,11zM5,18h14v2L5,20z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_download_for_offline_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M12,2C6.49,2 2,6.49 2,12s4.49,10 10,10s10,-4.49 10,-10S17.51,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20zM14.59,8.59L16,10l-4,4l-4,-4l1.41,-1.41L11,10.17V6h2v4.17L14.59,8.59zM17,17H7v-2h10V17z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_expand_circle_down_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M15.08,9.59L12,12.67L8.92,9.59L7.5,11l4.5,4.5l4.5,-4.5L15.08,9.59zM12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8s8,3.58 8,8S16.42,20 12,20z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_file_download_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M18,15v3H6v-3H4v3c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2v-3H18zM17,11l-1.41,-1.41L13,12.17V4h-2v8.17L8.41,9.59L7,11l5,5L17,11z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_home_24.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"#000000\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,5.69l5,4.5V18h-2v-6H9v6H7v-7.81l5,-4.5M12,3L2,12h3v8h6v-6h2v6h6v-8h3L12,3z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_input_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M21,3.01H3c-1.1,0 -2,0.9 -2,2V9h2V4.99h18v14.03H3V15H1v4.01c0,1.1 0.9,1.98 2,1.98h18c1.1,0 2,-0.88 2,-1.98v-14c0,-1.11 -0.9,-2 -2,-2zM11,16l4,-4 -4,-4v3H1v2h10v3zM21,3.01H3c-1.1,0 -2,0.9 -2,2V9h2V4.99h18v14.03H3V15H1v4.01c0,1.1 0.9,1.98 2,1.98h18c1.1,0 2,-0.88 2,-1.98v-14c0,-1.11 -0.9,-2 -2,-2zM11,16l4,-4 -4,-4v3H1v2h10v3z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_library_books_24.xml",
    "content": "<vector android:autoMirrored=\"true\" android:height=\"24dp\"\n    android:tint=\"#000000\" android:viewportHeight=\"24\"\n    android:viewportWidth=\"24\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM20,16L8,16L8,4h12v12zM10,9h8v2h-8zM10,12h4v2h-4zM10,6h8v2h-8z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_switch_access_shortcut_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M7.06,8.94L5,8l2.06,-0.94L8,5l0.94,2.06L11,8L8.94,8.94L8,11L7.06,8.94zM8,21l0.94,-2.06L11,18l-2.06,-0.94L8,15l-0.94,2.06L5,18l2.06,0.94L8,21zM4.37,12.37L3,13l1.37,0.63L5,15l0.63,-1.37L7,13l-1.37,-0.63L5,11L4.37,12.37zM12,12c0,-3.09 1.38,-5.94 3.44,-8L12,4V2h7v7h-2l0,-3.72c-1.8,1.74 -3,4.2 -3,6.72c0,3.32 2.1,6.36 5,7.82L19,22C14.91,20.41 12,16.35 12,12z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_timer_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M15,1H9v2h6V1zM11,14h2V8h-2V14zM19.03,7.39l1.42,-1.42c-0.43,-0.51 -0.9,-0.99 -1.41,-1.41l-1.42,1.42C16.07,4.74 14.12,4 12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9s9,-4.03 9,-9C21,10.88 20.26,8.93 19.03,7.39zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7s7,3.13 7,7S15.87,20 12,20z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_touch_app_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M18.19,12.44l-3.24,-1.62c1.29,-1 2.12,-2.56 2.12,-4.32c0,-3.03 -2.47,-5.5 -5.5,-5.5s-5.5,2.47 -5.5,5.5c0,2.13 1.22,3.98 3,4.89v3.26c-2.15,-0.46 -2.02,-0.44 -2.26,-0.44c-0.53,0 -1.03,0.21 -1.41,0.59L4,16.22l5.09,5.09C9.52,21.75 10.12,22 10.74,22h6.3c0.98,0 1.81,-0.7 1.97,-1.67l0.8,-4.71C20.03,14.32 19.38,13.04 18.19,12.44zM17.84,15.29L17.04,20h-6.3c-0.09,0 -0.17,-0.04 -0.24,-0.1l-3.68,-3.68l4.25,0.89V6.5c0,-0.28 0.22,-0.5 0.5,-0.5c0.28,0 0.5,0.22 0.5,0.5v6h1.76l3.46,1.73C17.69,14.43 17.91,14.86 17.84,15.29zM8.07,6.5c0,-1.93 1.57,-3.5 3.5,-3.5s3.5,1.57 3.5,3.5c0,0.95 -0.38,1.81 -1,2.44V6.5c0,-1.38 -1.12,-2.5 -2.5,-2.5c-1.38,0 -2.5,1.12 -2.5,2.5v2.44C8.45,8.31 8.07,7.45 8.07,6.5z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_update_disabled_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M20.94,13c-0.15,1.38 -0.62,2.67 -1.33,3.79l-1.47,-1.47c0.38,-0.71 0.65,-1.49 0.77,-2.32H20.94zM8.67,5.84C9.66,5.31 10.8,5 12,5c2.37,0 4.47,1.19 5.74,3H15v2h6V4h-2v2.36C17.35,4.32 14.83,3 12,3c-1.76,0 -3.4,0.51 -4.78,1.39L8.67,5.84zM11,7v1.17l2,2V7H11zM19.78,22.61l-3,-3C15.39,20.48 13.76,21 12,21c-4.97,0 -9,-4.03 -9,-9c0,-1.76 0.51,-3.4 1.39,-4.78L1.39,4.22l1.41,-1.41l18.38,18.38L19.78,22.61zM15.32,18.15L5.84,8.67C5.31,9.66 5,10.8 5,12c0,3.86 3.14,7 7,7C13.2,19 14.34,18.69 15.32,18.15z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_wifi_lock_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M21.98,11L24,8.98C20.93,5.9 16.69,4 12,4C7.31,4 3.07,5.9 0,8.98l6.35,6.36L12,21l3.05,-3.05V15c0,-0.45 0.09,-0.88 0.23,-1.29c0.54,-1.57 2.01,-2.71 3.77,-2.71H21.98z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M22,16v-1c0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2v1c-0.55,0 -1,0.45 -1,1v3c0,0.55 0.45,1 1,1h4c0.55,0 1,-0.45 1,-1v-3C23,16.45 22.55,16 22,16zM21,16h-2v-1c0,-0.55 0.45,-1 1,-1s1,0.45 1,1V16z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/outline_work_history_24.xml",
    "content": "<vector android:height=\"24dp\" android:tint=\"#000000\"\n    android:viewportHeight=\"24\" android:viewportWidth=\"24\"\n    android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M4,19V8h16v3.29c0.72,0.22 1.4,0.54 2,0.97V8c0,-1.11 -0.89,-2 -2,-2h-4V4c0,-1.11 -0.89,-2 -2,-2h-4C8.89,2 8,2.89 8,4v2H4C2.89,6 2.01,6.89 2.01,8L2,19c0,1.11 0.89,2 2,2h7.68c-0.3,-0.62 -0.5,-1.29 -0.6,-2H4zM10,4h4v2h-4V4z\"/>\n    <path android:fillColor=\"@android:color/white\" android:pathData=\"M18,13c-2.76,0 -5,2.24 -5,5s2.24,5 5,5s5,-2.24 5,-5S20.76,13 18,13zM19.65,20.35l-2.15,-2.15V15h1v2.79l1.85,1.85L19.65,20.35z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/transition_text_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:shape=\"rectangle\">\n\n    <corners android:radius=\"999dp\"/>\n    <solid android:color=\"?colorPrimary\" />\n    <padding\n        android:bottom=\"8dp\"\n        android:left=\"8dp\"\n        android:right=\"8dp\"\n        android:top=\"8dp\" />\n\n</shape>"
  },
  {
    "path": "app/src/main/res/drawable/undraw_arrow.xml",
    "content": "<vector android:height=\"7.6422195dp\" android:viewportHeight=\"20.94\"\n    android:viewportWidth=\"65.761\" android:width=\"24dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#01010C\" android:pathData=\"M3.07,14.35c14.779,-4.665 30.548,-5.69 45.762,-2.616 4.446,0.898 8.816,2.124 13.095,3.626 1.274,0.447 2.735,-0.508 3.075,-1.746 0.379,-1.379 -0.467,-2.627 -1.746,-3.075C47.822,5.122 31.259,3.636 15.118,6.305c-4.532,0.75 -8.998,1.841 -13.378,3.223C-1.317,10.494 -0.011,15.322 3.07,14.35h0Z\"/>\n    <path android:fillColor=\"#01010C\" android:pathData=\"M55.974,3.761l2.586,4.864 1.33,2.502 0.665,1.251c0.086,0.163 0.169,0.423 0.296,0.556 -0.515,-0.54 1.425,-2.154 0.513,-1.825 -0.805,0.29 -1.588,0.842 -2.345,1.244 -0.827,0.439 -1.655,0.878 -2.482,1.317 -1.655,0.878 -3.31,1.756 -4.965,2.633 -1.157,0.614 -1.608,2.318 -0.897,3.42 0.759,1.177 2.183,1.553 3.42,0.897 1.931,-1.024 3.862,-2.048 5.792,-3.072 0.919,-0.488 1.839,-0.975 2.758,-1.463 1.148,-0.609 2.344,-1.112 2.882,-2.385 0.549,-1.301 0.037,-2.543 -0.581,-3.706l-1.551,-2.919c-1.034,-1.946 -2.069,-3.891 -3.103,-5.837 -0.615,-1.156 -2.317,-1.608 -3.42,-0.897 -1.176,0.758 -1.554,2.184 -0.897,3.42h0Z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/undraw_drink_coffee.xml",
    "content": "<vector android:height=\"199.99359dp\" android:viewportHeight=\"623.63\"\n    android:viewportWidth=\"623.65\" android:width=\"200dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#dadbdc\" android:pathData=\"m311.82,623.63c-7.11,0 -14.2,-0.24 -21.06,-0.7 -7.09,-0.47 -14.19,-1.19 -21.12,-2.14 -3.05,-0.41 -5.81,-0.82 -8.44,-1.25 -7.81,-1.27 -15.76,-2.88 -23.62,-4.8 -2.69,-0.65 -5.33,-1.33 -7.83,-2.03 -0.88,-0.23 -1.78,-0.48 -2.67,-0.73 -3.8,-1.07 -7.48,-2.18 -10.92,-3.3 -0.22,-0.06 -0.48,-0.15 -0.74,-0.23 -3.11,-1 -6.35,-2.11 -9.62,-3.3 -2.76,-1 -5.56,-2.06 -8.56,-3.24 -6.25,-2.46 -12.51,-5.18 -18.61,-8.07 -2.54,-1.19 -5.19,-2.5 -8.11,-3.98 -0.52,-0.26 -1.05,-0.53 -1.57,-0.8l-0.6,-0.31c-34.28,-17.8 -64.67,-41.55 -90.31,-70.58C27.72,461.19 0,387.9 0,311.81c0,-83.29 32.44,-161.6 91.33,-220.49C150.22,32.43 228.53,0 311.82,0s161.6,32.43 220.5,91.32c58.9,58.89 91.33,137.2 91.33,220.49 0,48.94 -11.02,95.79 -32.74,139.25 -20.72,41.44 -51.05,78.43 -87.73,106.96 -8.62,6.72 -17.7,13.04 -26.98,18.8 -9.41,5.86 -19.28,11.29 -29.34,16.13 -2.24,1.08 -4.64,2.2 -7.56,3.51l-0.28,0.12c-0.36,0.16 -0.72,0.32 -1.08,0.47 -2.18,0.97 -4.4,1.92 -6.59,2.82l-0.99,0.42c-0.62,0.26 -1.2,0.5 -1.78,0.72 -7.43,3 -14.92,5.7 -22.26,8.01 -0.58,0.2 -1.17,0.38 -1.77,0.56l-0.52,0.16c-6.1,1.89 -12.52,3.65 -19.05,5.22 -23.79,5.74 -48.41,8.65 -73.16,8.65v0.02h0l-0,0ZM311.82,2c-82.76,0 -160.56,32.22 -219.08,90.74C34.23,151.25 2,229.05 2,311.81c0,75.61 27.54,148.42 77.55,205.03 25.48,28.84 55.67,52.44 89.73,70.12l0.6,0.31c0.51,0.27 1.03,0.53 1.55,0.79 2.91,1.48 5.54,2.78 8.06,3.96 6.06,2.87 12.28,5.57 18.49,8.01 2.98,1.18 5.76,2.23 8.5,3.22 3.25,1.18 6.47,2.28 9.57,3.28 0.24,0.08 0.47,0.15 0.7,0.22 3.45,1.12 7.09,2.22 10.87,3.29 0.87,0.25 1.76,0.5 2.64,0.73 2.5,0.69 5.11,1.37 7.78,2.02 7.82,1.91 15.71,3.52 23.48,4.77 2.61,0.43 5.35,0.84 8.38,1.25 6.88,0.94 13.94,1.66 20.98,2.12 6.82,0.46 13.86,0.7 20.92,0.7 24.6,0 49.05,-2.89 72.7,-8.59 6.49,-1.56 12.86,-3.31 18.94,-5.19l0.52,-0.16c0.58,-0.18 1.15,-0.35 1.73,-0.55 7.31,-2.3 14.76,-4.98 22.15,-7.97 0.58,-0.23 1.14,-0.46 1.7,-0.69l1.23,-0.51c2.11,-0.87 4.25,-1.79 6.37,-2.73 0.37,-0.16 0.71,-0.31 1.06,-0.47l0.28,-0.12c2.9,-1.31 5.29,-2.42 7.51,-3.49 10,-4.81 19.81,-10.2 29.16,-16.03 9.22,-5.72 18.24,-12.01 26.81,-18.68 36.44,-28.36 66.58,-65.11 87.17,-106.28 21.58,-43.17 32.53,-89.72 32.53,-138.35 0,-82.76 -32.23,-160.56 -90.75,-219.07C472.39,34.22 394.58,2 311.82,2Z\"/>\n    <path android:fillColor=\"#f3a3a6\" android:pathData=\"M273.97,426.13l75.77,18.15l-8.79,-106.18l-66.92,5.54l-0.06,82.49z\"/>\n    <path android:fillColor=\"#f3a3a6\" android:pathData=\"M328.17,294.74m-73.76,0a73.76,73.76 0,1 1,147.52 0a73.76,73.76 0,1 1,-147.52 0\"/>\n    <path android:fillColor=\"#dadbdc\" android:pathData=\"m406.02,608.08c-0.59,0.2 -1.17,0.38 -1.76,0.56 -0.17,0.05 -0.34,0.11 -0.51,0.16 -6.25,1.94 -12.59,3.67 -19,5.21 -23.39,5.64 -47.82,8.62 -72.93,8.62 -7.06,0 -14.06,-0.23 -20.99,-0.7 -7.09,-0.47 -14.11,-1.18 -21.05,-2.13 -2.82,-0.38 -5.62,-0.79 -8.41,-1.25 -7.95,-1.29 -15.81,-2.9 -23.55,-4.79 -2.61,-0.63 -5.21,-1.3 -7.8,-2.02 -0.89,-0.23 -1.78,-0.48 -2.66,-0.73 -3.65,-1.03 -7.28,-2.12 -10.88,-3.29 -0.24,-0.07 -0.49,-0.15 -0.73,-0.23 -3.22,-1.04 -6.42,-2.14 -9.6,-3.29 -2.86,-1.03 -5.7,-2.11 -8.53,-3.23 -6.29,-2.48 -12.47,-5.16 -18.55,-8.04l2.34,-10.6 8.11,-36.72 17.61,-79.78 17.8,-80.62 46.77,1.3h0.02l2.28,0.07 71.13,1.98 31.12,0.87 29.77,218.65h0l0,-0Z\"/>\n    <path android:fillColor=\"#dadbdc\" android:pathData=\"m475.68,575.97c-9.42,5.87 -19.19,11.24 -29.25,16.08 -2.49,1.2 -5.01,2.36 -7.54,3.5 -0.45,0.2 -0.89,0.4 -1.34,0.59 -2.18,0.97 -4.37,1.91 -6.58,2.82h0l-0.99,0.42c-0.58,0.24 -1.16,0.48 -1.75,0.71 -7.27,2.94 -14.67,5.62 -22.2,7.99 -0.59,0.2 -1.17,0.38 -1.76,0.56l-65.24,-166.93 -4.41,-11.27 -12.3,-31.49 -4.08,-10.43 26.93,0.42 31.09,0.49c28.22,3.61 51.62,23.58 59.63,50.87l39.8,135.67h-0.01v-0Z\"/>\n    <path android:fillColor=\"#2f2e43\" android:pathData=\"m276.43,328.44c2.62,-0.44 5.24,-0.89 7.86,-1.33 0.62,-14.01 1.97,-29.64 12.46,-38.95 5.78,-5.13 14.14,-8.12 17.01,-15.3 2.38,-5.95 0.16,-13.26 3.48,-18.74 3.49,-5.77 11.29,-6.8 18.03,-7.22 10.55,-0.65 21.29,-1.29 31.56,1.21 10.27,2.51 20.18,8.69 24.56,18.31 1.35,2.96 2.13,6.15 2.91,9.31 2.63,10.69 6.66,31.03 6.66,31.03 0,0 0.78,-4.21 3,-12.4 4.53,-6.48 10.06,-12.46 12.72,-19.9 3.2,-8.96 1.79,-18.97 -1.35,-27.94 -7.13,-20.41 -23.67,-37.66 -44.27,-44.22 -20.61,-6.55 -40.1,-10.26 -55.5,4.92 -2.89,2.85 -5.49,6.03 -8.79,8.39 -6.1,4.37 -13.89,5.47 -20.77,8.49 -15.31,6.72 -29.15,22.88 -32.6,39.24 -3.45,16.36 -1.65,33.31 0.17,49.94 1.57,14.34 8.38,30.33 20.32,38.43 0.49,-7.34 0.98,-14.67 1.47,-22.01l1.06,-1.25h0.01v-0.01Z\"/>\n    <path android:fillColor=\"#dadbdc\" android:pathData=\"m317.26,397.4l-0.72,1.18 -20.14,32.92 -29.86,48.84 -6.05,9.89 -22.06,36.08s-7.16,10.07 -19.24,22.98l-0.04,0.04c-4.39,4.68 -9.42,9.73 -14.99,14.8 -0.04,0.05 -0.08,0.09 -0.13,0.12 -6.8,6.2 -14.4,12.43 -22.62,18.08 -3.38,2.33 -6.86,4.55 -10.42,6.63 -0.73,-0.36 -1.45,-0.74 -2.17,-1.11 -34.22,-17.77 -64.72,-41.71 -90.02,-70.35 26.41,-42.18 78.67,-89.48 112.34,-117.65 19.05,-15.95 44.5,-21.96 68.66,-16.18l11.9,2.84 2.3,0.55 43.26,10.34h-0Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"m411.22,387.25c-12.97,-4.67 -47.3,-4.69 -62.7,0.51 -2.99,1.01 -4.8,4.05 -4.28,7.16l0.61,3.69c-1.34,-0.2 -2.65,-0.58 -3.89,-1.15 -3.67,-1.68 -10.9,-3.96 -18.2,-0.32 -5.1,2.54 -8.69,7.33 -9.95,12.9 -3.01,13.32 4.58,20.69 4.58,20.69l10.11,9.49c8.47,7.94 17.71,15.02 27.58,21.12l0.2,0.12 -3.6,-21.66c-2.03,3.57 -6.62,4.74 -10.11,2.58 -8.82,-5.46 -23.23,-16.4 -21.48,-28.82 1.22,-8.66 6.03,-10.5 10.65,-10.11 5.17,0.44 9.68,3.69 11.89,8.38 0.53,1.12 1.4,2.04 2.48,2.64l2.6,1.42 7.62,45.91c0.34,2.06 1.66,3.84 3.53,4.76 17.92,8.79 37.26,4.23 43.95,2.18 1.53,-0.47 2.84,-1.48 3.66,-2.86l1.44,-2.39c0.5,-0.82 0.8,-1.75 0.9,-2.7l6.65,-66.82c0.29,-2.95 -1.46,-5.71 -4.25,-6.72h0.01Z\"/>\n    <path android:fillColor=\"#dedfe0\" android:pathData=\"M350.04,390.8a30.13,2.84 0,1 0,60.26 0a30.13,2.84 0,1 0,-60.26 0z\"/>\n    <path android:fillColor=\"#f3a3a6\" android:pathData=\"m319.98,447.72c16.35,-12.51 22.82,-31.32 14.45,-42.01 -8.36,-10.69 -28.39,-9.22 -44.75,3.3 -6.6,4.91 -11.88,11.37 -15.37,18.84l-68.56,53.89 27.22,32.56 64.7,-56.59c8.19,-1.47 15.84,-4.9 22.3,-9.99h0.01Z\"/>\n    <path android:fillColor=\"#dadbdc\" android:pathData=\"M274.62,494.54l-27.12,-47.7l-98.69,46.44l55.22,70.98l70.59,-69.72z\"/>\n    <path android:fillAlpha=\"0.1\" android:fillColor=\"#272223\"\n        android:pathData=\"m215.47,461.91s-71.94,52.67 -69.28,52.38c2.66,-0.29 38.13,-19.8 38.13,-19.8l31.15,-32.58h0v0Z\" android:strokeAlpha=\"0.1\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/undraw_login_re.xml",
    "content": "<vector android:height=\"119.57241dp\" android:viewportHeight=\"520.14\"\n    android:viewportWidth=\"870\" android:width=\"200dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#f2f2f2\" android:pathData=\"M666.09,514.26c-11.14,-9.41 -17.9,-24.28 -16.13,-38.75s12.76,-27.78 27.02,-30.85 30.5,5.43 34.83,19.36c2.38,-26.85 5.13,-54.82 19.4,-77.68 12.92,-20.7 35.31,-35.51 59.57,-38.16s49.8,7.36 64.93,26.51 18.83,46.99 8.24,68.97c-7.81,16.19 -22.19,28.25 -37.26,38.05a240.45,240.45 0,0 1,-164.45 35.98Z\"/>\n    <path android:fillColor=\"#fff\" android:pathData=\"M831.73,356.08a393.41,393.41 0,0 0,-54.83 54.44,394.56 394.56,0 0,0 -61.75,103.19c-1.11,2.72 3.31,3.91 4.41,1.22A392.34,392.34 0,0 1,834.96 359.31c2.28,-1.86 -0.97,-5.08 -3.24,-3.24Z\"/>\n    <path android:fillColor=\"#f2f2f2\" android:pathData=\"M280.07,511.7c15.3,-12.93 24.59,-33.35 22.15,-53.23s-17.53,-38.16 -37.11,-42.38 -41.9,7.46 -47.84,26.59c-3.27,-36.87 -7.04,-75.29 -26.65,-106.69 -17.75,-28.43 -48.5,-48.78 -81.82,-52.42s-68.4,10.11 -89.19,36.41 -25.87,64.53 -11.31,94.73c10.72,22.24 30.48,38.8 51.17,52.26 66.03,42.97 147.94,60.88 225.88,49.41\"/>\n    <path android:fillColor=\"#fff\" android:pathData=\"M52.57,294.44a540.35,540.35 0,0 1,75.3 74.78A548.08,548.08 0,0 1,187.26 457.11a545.84,545.84 0,0 1,25.43 53.85c1.53,3.74 -4.55,5.37 -6.06,1.67a536.36,536.36 0,0 0,-49.01 -92.73A539.73,539.73 0,0 0,91.89 338.7a538.44,538.44 0,0 0,-43.77 -39.81c-3.14,-2.55 1.33,-6.98 4.44,-4.44Z\"/>\n    <path android:fillColor=\"#f2f2f2\" android:pathData=\"M624.5,519h-365v-374.5c0,-79.68 64.82,-144.5 144.5,-144.5h76c79.68,0 144.5,64.82 144.5,144.5Z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M548.5,519h-289v-374.5a143.38,143.38 0,0 1,27.6 -84.94c0.66,-0.9 1.33,-1.8 2.01,-2.68a144.47,144.47 0,0 1,30.75 -29.85c0.66,-0.48 1.32,-0.95 1.99,-1.42a144.16,144.16 0,0 1,31.47 -16.46c0.66,-0.25 1.33,-0.5 2.01,-0.74a144.02,144.02 0,0 1,31.11 -7.34c0.66,-0.09 1.33,-0.16 2.01,-0.23a146.29,146.29 0,0 1,31.11 0c0.67,0.07 1.35,0.14 2.01,0.23a143.99,143.99 0,0 1,31.1 7.34c0.67,0.24 1.35,0.49 2.01,0.74a143.8,143.8 0,0 1,31.11 16.22c0.67,0.46 1.34,0.93 2.01,1.4a145.99,145.99 0,0 1,18.38 15.56,144.3 144.3,0 0,1 12.72,14.55c0.68,0.88 1.34,1.77 2.01,2.68A143.38,143.38 0,0 1,548.5 144.5Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M525,335.5m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0\"/>\n    <path android:fillColor=\"#ffb8b8\" android:pathData=\"M594.6,507.78l-12.26,0l-5.83,-47.29l18.1,0l-0,47.29z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M573.58,504.28h23.64a0,0 0,0 1,0 0v14.89a0,0 0,0 1,0 0H558.69a0,0 0,0 1,0 0v0a14.89,14.89 0,0 1,14.89 -14.89Z\"/>\n    <path android:fillColor=\"#ffb8b8\" android:pathData=\"M655.6,507.78l-12.26,0l-5.83,-47.29l18.1,0l-0,47.29z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M634.58,504.28h23.64a0,0 0,0 1,0 0v14.89a0,0 0,0 1,0 0H619.69a0,0 0,0 1,0 0v0a14.89,14.89 0,0 1,14.89 -14.89Z\"/>\n    <path android:fillColor=\"#ffb8b8\" android:pathData=\"M533.1,338.67a10.74,10.74 0,0 1,4.51 -15.84l41.68,-114.87L599.79,219.15 552.21,328.92a10.8,10.8 0,0 1,-19.11 9.75Z\"/>\n    <path android:fillColor=\"#ffb8b8\" android:pathData=\"M649.34,360.25a10.74,10.74 0,0 1,-2.89 -16.22L633.53,222.53l23.34,1.07L662.24,343.11a10.8,10.8 0,0 1,-12.9 17.14Z\"/>\n    <path android:fillColor=\"#ffb8b8\" android:pathData=\"M612.11,162.12m-24.56,0a24.56,24.56 0,1 1,49.12 0a24.56,24.56 0,1 1,-49.12 0\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M649.18,332.62L575.13,332.62l0.09,-0.58c0.13,-0.86 13.2,-86.44 3.56,-114.44a11.81,11.81 0,0 1,6.07 -14.58h0c13.77,-6.49 40.21,-14.47 62.52,4.91a28.23,28.23 0,0 1,9.46 23.4Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M589.35,258.25 L556.02,251.49l15.63,-37.03a14,14 0,0 1,27.11 7Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M632.05,270.81l-2,-45.94c-1.52,-8.64 3.42,-16.8 11.03,-18.13 7.61,-1.33 15.03,4.66 16.56,13.36l7.53,42.93Z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M646.72,327.12c11.91,45.38 13.21,103.07 10,166l-16,-2 -29,-120 -16,122 -18,-1c-5.38,-66.03 -10.61,-122.72 -2,-160Z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M628.29,181.1c-4.58,4.88 -13.09,2.26 -13.69,-4.41a8.05,8.05 0,0 1,0.01 -1.56c0.31,-2.95 2.01,-5.64 1.61,-8.75a4.59,4.59 0,0 0,-0.84 -2.15c-3.65,-4.89 -12.22,2.19 -15.67,-2.24 -2.11,-2.71 0.37,-6.99 -1.25,-10.02 -2.14,-4 -8.48,-2.03 -12.45,-4.22 -4.42,-2.44 -4.16,-9.23 -1.25,-13.35 3.55,-5.03 9.78,-7.72 15.92,-8.11s12.25,1.27 17.99,3.51c6.52,2.54 12.99,6.05 17,11.79 4.88,6.97 5.35,16.35 2.91,24.5C637.1,171.06 632.03,177.12 628.29,181.1Z\"/>\n    <path android:fillColor=\"#3f3d56\" android:pathData=\"M839.98,519.64h-738.29a1.19,1.19 0,0 1,0 -2.38h738.29a1.19,1.19 0,0 1,0 2.38Z\"/>\n    <path android:fillColor=\"#fff\" android:pathData=\"M469,410.5L339,410.5a6.47,6.47 0,0 1,-6.5 -6.42L332.5,113.92a6.47,6.47 0,0 1,6.5 -6.42L469,107.5a6.47,6.47 0,0 1,6.5 6.42L475.5,404.08A6.47,6.47 0,0 1,469 410.5Z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M332.5,201.39h143v2h-143z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M333,315.5h143v2h-143z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M377.5,107.5h2v304h-2z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M427.5,107.5h2v304h-2z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/undraw_no_data_re_kwbl.xml",
    "content": "<vector android:height=\"195.22266dp\" android:viewportHeight=\"632.17\"\n    android:viewportWidth=\"647.64\" android:width=\"200dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#f2f2f2\" android:pathData=\"M411.15,142.17L236.64,142.17a15.02,15.02 0,0 0,-15 15v387.85l-2,0.61 -42.81,13.11a8.01,8.01 0,0 1,-9.99 -5.31L39.5,137.48a8,8 0,0 1,5.31 -9.99l65.97,-20.2 191.25,-58.54 65.97,-20.2a7.99,7.99 0,0 1,9.99 5.3l32.55,106.32Z\"/>\n    <path android:fillColor=\"#3f3d56\" android:pathData=\"M449.23,140.17l-39.23,-128.14a16.99,16.99 0,0 0,-21.23 -11.28l-92.75,28.39L104.78,87.69l-92.75,28.4a17.02,17.02 0,0 0,-11.28 21.23l134.08,437.93a17.03,17.03 0,0 0,16.26 12.03,16.79 16.79,0 0,0 4.97,-0.75l63.58,-19.46 2,-0.62v-2.09l-2,0.61 -64.17,19.65a15.01,15.01 0,0 1,-18.73 -9.95l-134.07,-437.94a14.98,14.98 0,0 1,9.95 -18.73l92.75,-28.4 191.24,-58.54 92.75,-28.4a15.16,15.16 0,0 1,4.41 -0.66,15.01 15.01,0 0,1 14.32,10.61l39.05,127.56 0.62,2h2.08Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M122.68,127.82a9.02,9.02 0,0 1,-8.61 -6.37l-12.88,-42.07a9,9 0,0 1,5.97 -11.24l175.94,-53.86a9.01,9.01 0,0 1,11.24 5.97l12.88,42.07a9.01,9.01 0,0 1,-5.97 11.24L125.31,127.43A8.98,8.98 0,0 1,122.68 127.82Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M190.15,24.95m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0\"/>\n    <path android:fillColor=\"#fff\" android:pathData=\"M190.15,24.95m-12.66,0a12.66,12.66 0,1 1,25.33 0a12.66,12.66 0,1 1,-25.33 0\"/>\n    <path android:fillColor=\"#e6e6e6\" android:pathData=\"M602.64,582.17h-338a8.51,8.51 0,0 1,-8.5 -8.5v-405a8.51,8.51 0,0 1,8.5 -8.5h338a8.51,8.51 0,0 1,8.5 8.5v405A8.51,8.51 0,0 1,602.64 582.17Z\"/>\n    <path android:fillColor=\"#3f3d56\" android:pathData=\"M447.14,140.17h-210.5a17.02,17.02 0,0 0,-17 17v407.8l2,-0.61v-407.19a15.02,15.02 0,0 1,15 -15L447.76,142.17ZM630.64,140.17h-394a17.02,17.02 0,0 0,-17 17v458a17.02,17.02 0,0 0,17 17h394a17.02,17.02 0,0 0,17 -17v-458A17.02,17.02 0,0 0,630.64 140.17ZM645.64,615.17a15.02,15.02 0,0 1,-15 15h-394a15.02,15.02 0,0 1,-15 -15v-458a15.02,15.02 0,0 1,15 -15h394a15.02,15.02 0,0 1,15 15Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M525.64,184.17h-184a9.01,9.01 0,0 1,-9 -9v-44a9.01,9.01 0,0 1,9 -9h184a9.01,9.01 0,0 1,9 9v44A9.01,9.01 0,0 1,525.64 184.17Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M433.64,105.17m-20,0a20,20 0,1 1,40 0a20,20 0,1 1,-40 0\"/>\n    <path android:fillColor=\"#fff\" android:pathData=\"M433.64,105.17m-12.18,0a12.18,12.18 0,1 1,24.36 0a12.18,12.18 0,1 1,-24.36 0\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable/undraw_personal_file_re.xml",
    "content": "<vector android:height=\"151.75777dp\" android:viewportHeight=\"544.56\"\n    android:viewportWidth=\"717.67\" android:width=\"200dp\" xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M287.19,52.53c-8.74,15.06 7.72,40.44 -8.87,45.71l1.37,-1.37c10.02,-12.32 -10.92,-38.4 -0.9,-50.72a30.1,30.1 0,0 0,3.98 -5.92\"/>\n    <path android:fillColor=\"?colorSecondary\" android:pathData=\"M369.07,273.51a10.5,10.5 0,0 0,-10.19 -12.46L337.27,198.26l-11.96,15.25L348.16,272.19a10.55,10.55 0,0 0,20.92 1.33Z\"/>\n    <path android:fillColor=\"#6c63ff\" android:pathData=\"M274.07,121.91s-0.67,-22.73 19.65,-9.71S358.3,247.2 358.3,247.2l-22.02,11.92L286.28,147.49Z\"/>\n    <path android:fillColor=\"#ffb6b6\" android:pathData=\"M334.03,511.49l-10.15,4.34l-21.56,-37.09l14.98,-6.4l16.73,39.15z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M346.91,526.78l-7.28,3.11 -4.24,-6.32 -0.39,8.29 -19.31,8.25a4.72,4.72 0,0 1,-5.85 -6.86l10.87,-17.24 -2.97,-6.95 16.63,-5.96Z\"/>\n    <path android:fillColor=\"#ffb6b6\" android:pathData=\"M174.92,524.07l-11.02,-0.54l-3.17,-42.78l16.27,0.8l-2.08,42.52z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M179.81,543.45l-7.91,-0.39 -1.05,-7.53 -3.98,7.29 -20.97,-1.02a4.72,4.72 0,0 1,-2.26 -8.72l17.31,-10.75 0.37,-7.55 17.56,1.91Z\"/>\n    <path android:fillColor=\"?colorSecondary\" android:pathData=\"M499.75,517.25a3.56,3.56 0,0 0,2.52 -6.2c-0.09,-0.36 -0.16,-0.61 -0.25,-0.97a9.57,9.57 0,0 1,17.75 -0.34c4.32,9.85 9.88,20.03 7.27,30.94 17.59,-38.23 11.04,-85.51 -15.81,-117.8 -7.37,-3.97 -13.39,-11.09 -15.01,-19.41 3.64,1.2 8.14,-1.8 5.37,-5.6 -1.2,-1.45 -2.41,-2.89 -3.6,-4.34 13.65,-14.82 30.3,8.11 15.31,28.07a114.26,114.26 0,0 1,13.02 19.95,48.04 48.04,0 0,1 2.66,-22.34c2.68,-6.65 7.77,-12.28 12.25,-18.04 5.44,-7.03 16.81,-3.92 17.64,4.93 -5.07,1.72 -5.66,9.07 0.17,10.02 -1.37,16.48 -11.98,31.72 -26.73,39.08a114.71,114.71 0,0 1,6.72 47.89c2.43,-19.01 22.77,-23.81 36.94,-31.49a5.55,5.55 0,0 1,8.52 5.54,32.05 32.05,0 0,0 -5.59,3.02 4.84,4.84 0,0 0,2.33 8.82c-7.01,17.84 -25.46,29.95 -44.53,30.06a117.93,117.93 0,0 1,-7.7 23.2l-28.3,0.27c-0.1,-0.31 -0.2,-0.64 -0.29,-0.95a32.15,32.15 0,0 0,7.83 -0.54c-7.01,-8.14 -12.41,-12.27 -8.48,-23.77Z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M202.77,245.99s-22.42,61.1 -22.78,67.93 -6.76,93.3 -12.12,98.32 -21.76,82.91 -9,89 53,-4 53,-4l14,-92 4.76,-70.48s14.48,165.98 40.74,165.49 58.26,-10.49 58.26,-10.49L292.87,389.24s0.52,-119 -8,-143S202.77,245.99 202.77,245.99Z\"/>\n    <path android:fillColor=\"?colorSurface\" android:pathData=\"M269.3,88.57l-30.02,2.75 -4.84,14.85s-25.13,13.8 -19.56,20.07 -1.24,48.52 -1.24,48.52l1.54,34.29s-1.65,23.76 -6.59,29.23 -17.87,18.9 -8.74,12.48c32.04,-22.52 88.04,-3.52 88.04,-3.52l-8,-49s18.17,-80.22 11,-87 -13.94,-7.63 -13.94,-7.63Z\"/>\n    <path android:fillColor=\"#ffb8b8\" android:pathData=\"M111.53,244a10.5,10.5 0,0 0,7.9 -14.02l50.64,-42.96 -18.55,-5.6L105.17,224.04a10.55,10.55 0,0 0,6.37 19.97Z\"/>\n    <path android:fillColor=\"?colorSecondary\" android:pathData=\"M240.14,131.63s9.98,-20.43 -13.91,-16.94 -114.46,96.4 -114.46,96.4L126.93,231.01l91.54,-81.11Z\"/>\n    <path android:fillColor=\"#e6e6e6\" android:pathData=\"M201.24,96.96 L106.54,218.29a10.08,10.08 0,0 0,1.74 14.13c21.99,53.4 87.79,93 165.19,128.94a10.07,10.07 0,0 0,14.13 -1.74l94.7,-121.33a10.07,10.07 0,0 0,-1.74 -14.13c-64.95,-36.68 -120.78,-79.17 -165.19,-128.94A10.08,10.08 0,0 0,201.24 96.96Z\"/>\n    <path android:fillColor=\"#fff\" android:pathData=\"M375.65,235.53l-28.83,36.93a107.91,107.91 0,0 1,-151.02 18.61L115.02,228.01a5.73,5.73 0,0 1,-1 -8.04l91.51,-117.24a5.73,5.73 0,0 1,8.04 -0.98c40.87,52.77 95.57,93.83 161.09,125.74A5.73,5.73 0,0 1,375.65 235.53Z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M199.35,163.2 L180.58,187.25a3.05,3.05 0,0 1,-4.81 -3.75l18.77,-24.05a3.05,3.05 0,1 1,4.81 3.75Z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M234.57,145.36l-41.23,52.82a3.05,3.05 0,0 1,-4.81 -3.75L229.76,141.6a3.05,3.05 0,1 1,4.81 3.75Z\"/>\n    <path android:fillColor=\"?colorSecondary\" android:pathData=\"M164.25,213.36m-20.1,0a20.1,20.1 0,1 1,40.19 0a20.1,20.1 0,1 1,-40.19 0\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M236.76,187.1l-50.64,64.87a3.07,3.07 0,0 1,-4.81 -3.75l50.64,-64.87a3.07,3.07 0,0 1,4.81 3.75Z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M269.6,172.29l-70.68,90.54a3.07,3.07 0,0 1,-4.81 -3.75l70.68,-90.54a3.07,3.07 0,0 1,4.81 3.75Z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M269.36,212.55l-50.64,64.87a3.07,3.07 0,0 1,-4.81 -3.75l50.64,-64.87a3.07,3.07 0,0 1,4.81 3.75Z\"/>\n    <path android:fillColor=\"?colorSecondary\" android:pathData=\"M336.36,220.55l-50.64,64.87a3.07,3.07 0,0 1,-4.81 -3.75l50.64,-64.87a3.07,3.07 0,0 1,4.81 3.75Z\"/>\n    <path android:fillColor=\"#ccc\" android:pathData=\"M302.21,197.74l-70.68,90.54a3.07,3.07 0,0 1,-4.81 -3.75l70.68,-90.54a3.07,3.07 0,0 1,4.81 3.75Z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M218.96,50.24A29.82,29.82 0,1 0,270.26 29.56l-0.14,-0.14c-0.24,-0.25 -0.48,-0.5 -0.73,-0.74a0.01,0.01 0,0 1,-0.01 -0.01c-0.31,-0.29 -0.62,-0.57 -0.94,-0.85a29.82,29.82 0,0 0,-49.47 22.43Z\"/>\n    <path android:fillColor=\"#ffb8b8\" android:pathData=\"M256.13,57.14m-25.01,0a25.01,25.01 0,1 1,50.02 0a25.01,25.01 0,1 1,-50.02 0\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M229.47,63.81c-2.44,-11.02 1.09,-23.36 8.79,-30.71a28.2,28.2 0,0 1,29.45 -5.71c0.63,0.25 1.26,0.53 1.88,0.82l0.29,0.14v0.04c0.06,0.04 0.11,0.08 0.17,0.12a0.96,0.96 0,0 0,0.41 0.23,15.42 15.42,0 0,1 11.63,4.85c3.88,4.21 5.7,11 5.14,19.14l-0.02,0.25 -0.22,0.14a85.46,85.46 0,0 1,-9.12 5.03c-10.98,5.16 -21,6.12 -30.63,2.92l-0.18,-0.06 -4.04,-6.78c-0.83,4.67 -0.39,20.17 -5.15,21.01l-8.3,-10.97Z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M176.83,85.58c8.51,-4.39 -2.43,-20.33 -0.24,-29.66 2.2,-9.32 18.04,-12.32 19.05,-21.84s3.38,-19.35 9.67,-26.57c4.02,-4.62 9.93,-8.03 16.02,-7.45a14.41,14.41 0,0 1,12.63 17.79c1.73,-2.46 6.22,-1.93 7.33,0.87 0.99,2.49 -1.19,5.5 -3.76,5.72 -3.36,4.15 -7.21,8.55 -12.47,9.39a5.68,5.68 0,0 1,-4.84 -1.12c-1.24,-1.19 -1.33,-3.57 0.13,-4.46 -6.62,2.63 -10.5,9.78 -11.48,16.83 -0.98,7.05 0.38,14.19 1.27,21.25s1.28,14.49 -1.49,21.05c-3.27,7.75 -10.8,13.3 -19.03,15.08s-16.98,0.04 -24.42,-3.88c-7.44,-3.92 -13.65,-9.91 -18.72,-16.62C155.23,88.17 167.31,90.49 176.83,85.58Z\"/>\n    <path android:fillColor=\"#2f2e41\" android:pathData=\"M244.19,55.53c-8.74,15.06 7.72,40.44 -8.87,45.71l1.37,-1.37c10.02,-12.32 -10.92,-38.4 -0.9,-50.72a30.1,30.1 0,0 0,3.98 -5.92\"/>\n    <path android:fillColor=\"#fd6584\" android:pathData=\"M230.64,63.58s7.41,-27.65 39.16,-34.03c0.04,-0.01 0.16,-0.06 0.31,-0.13 0.1,-0.06 0.21,-0.12 0.33,-0.18 -0.36,-0.2 -0.7,-0.38 -1.06,-0.56a0.01,0.01 0,0 1,-0.01 -0.01c-0.31,-0.29 -0.62,-0.57 -0.94,-0.85l-0.91,0.04S235.66,22.81 230.64,63.58Z\"/>\n    <path android:fillColor=\"?colorSecondary\" android:pathData=\"M0,543.37a1.19,1.19 0,0 0,1.19 1.19h715.29a1.19,1.19 0,0 0,0 -2.38L1.19,542.18A1.19,1.19 0,0 0,0 543.37Z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_arrow_back.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z\" />\n\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_explore_outline.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM6.5,17.5l7.51,-3.49L17.5,6.5 9.99,9.99 6.5,17.5zM12,10.9c0.61,0 1.1,0.49 1.1,1.1s-0.49,1.1 -1.1,1.1 -1.1,-0.49 -1.1,-1.1 0.49,-1.1 1.1,-1.1z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_look_more.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\"\n    android:tint=\"#333333\">\n  <group android:scaleX=\"1.25\"\n      android:scaleY=\"1.25\"\n      android:translateX=\"-3\"\n      android:translateY=\"-3\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_manga_info_main.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\"\n    android:tint=\"?textColorMe\"\n    android:alpha=\"0.6\">\n  <path\n      android:fillColor=\"@android:color/white\"\n      android:pathData=\"M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_manga_search.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_person_center.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M12,5.9c1.16,0 2.1,0.94 2.1,2.1s-0.94,2.1 -2.1,2.1S9.9,9.16 9.9,8s0.94,-2.1 2.1,-2.1m0,9c2.97,0 6.1,1.46 6.1,2.1v1.1L5.9,18.1L5.9,17c0,-0.64 3.13,-2.1 6.1,-2.1M12,4C9.79,4 8,5.79 8,8s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,13c-2.67,0 -8,1.34 -8,4v3h16v-3c0,-2.66 -5.33,-4 -8,-4z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_setting_outline.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:tint=\"?colorControlNormal\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98 0,-0.34 -0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.09,-0.16 -0.26,-0.25 -0.44,-0.25 -0.06,0 -0.12,0.01 -0.17,0.03l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.06,-0.02 -0.12,-0.03 -0.18,-0.03 -0.17,0 -0.34,0.09 -0.43,0.25l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98 0,0.33 0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.09,0.16 0.26,0.25 0.44,0.25 0.06,0 0.12,-0.01 0.17,-0.03l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.06,0.02 0.12,0.03 0.18,0.03 0.17,0 0.34,-0.09 0.43,-0.25l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM17.45,11.27c0.04,0.31 0.05,0.52 0.05,0.73 0,0.21 -0.02,0.43 -0.05,0.73l-0.14,1.13 0.89,0.7 1.08,0.84 -0.7,1.21 -1.27,-0.51 -1.04,-0.42 -0.9,0.68c-0.43,0.32 -0.84,0.56 -1.25,0.73l-1.06,0.43 -0.16,1.13 -0.2,1.35h-1.4l-0.19,-1.35 -0.16,-1.13 -1.06,-0.43c-0.43,-0.18 -0.83,-0.41 -1.23,-0.71l-0.91,-0.7 -1.06,0.43 -1.27,0.51 -0.7,-1.21 1.08,-0.84 0.89,-0.7 -0.14,-1.13c-0.03,-0.31 -0.05,-0.54 -0.05,-0.74s0.02,-0.43 0.05,-0.73l0.14,-1.13 -0.89,-0.7 -1.08,-0.84 0.7,-1.21 1.27,0.51 1.04,0.42 0.9,-0.68c0.43,-0.32 0.84,-0.56 1.25,-0.73l1.06,-0.43 0.16,-1.13 0.2,-1.35h1.39l0.19,1.35 0.16,1.13 1.06,0.43c0.43,0.18 0.83,0.41 1.23,0.71l0.91,0.7 1.06,-0.43 1.27,-0.51 0.7,1.21 -1.07,0.85 -0.89,0.7 0.14,1.13zM12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_swith_horiz.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\"\n    android:tint=\"#333333\"\n    android:alpha=\"0.6\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M6.99,11L3,15l3.99,4v-3H14v-2H6.99v-3zM21,9l-3.99,-4v3H10v2h7.01v3L21,9z\"/>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_swith_vert.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:alpha=\"0.6\"\n    android:tint=\"#333333\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\">\n\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M16,17.01V10h-2v7.01h-3L15,21l4,-3.99h-3zM9,3L5,6.99h3V14h2V6.99h3L9,3z\" />\n\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-anydpi/ic_trend_up.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"24dp\"\n    android:height=\"24dp\"\n    android:viewportWidth=\"24\"\n    android:viewportHeight=\"24\"\n    android:tint=\"#333333\"\n    android:autoMirrored=\"true\">\n  <group android:scaleX=\"1.0909091\"\n      android:scaleY=\"1.0909091\"\n      android:translateX=\"-1.0909091\"\n      android:translateY=\"-1.0909091\">\n    <path\n        android:fillColor=\"@android:color/white\"\n        android:pathData=\"M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z\"/>\n  </group>\n</vector>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_manga_reader.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.coordinatorlayout.widget.CoordinatorLayout 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:id=\"@+id/manga_reader_root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:background=\"@android:color/black\"\n    tools:context=\".MangaReaderActivity\">\n\n    <androidx.fragment.app.FragmentContainerView\n        android:id=\"@+id/manga_reader_container\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:descendantFocusability=\"blocksDescendants\" />\n\n    <com.shicheeng.copymanga.view.TransitionTextview\n        android:id=\"@+id/manga_reader_circular_progress_indicator\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"top|center\"\n        android:layout_marginTop=\"36dp\"\n        android:background=\"@drawable/transition_text_background\"\n        android:drawablePadding=\"16dp\"\n        android:text=\"@string/in_loading_next_chapter\"\n        android:textColor=\"?colorOnPrimary\" />\n\n    <androidx.appcompat.widget.AppCompatTextView\n        android:id=\"@+id/manga_reader_page_indicator\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|center\"\n        android:layout_marginBottom=\"24dp\"\n        android:elevation=\"1dp\"\n        android:shadowColor=\"@android:color/black\"\n        android:shadowDx=\"1.5\"\n        android:shadowDy=\"1.3\"\n        android:shadowRadius=\"1.6\"\n        android:text=\"@string/in_loading_next_chapter\"\n        android:textColor=\"@android:color/white\"\n        android:textStyle=\"bold\" />\n\n\n    <com.google.android.material.appbar.MaterialToolbar\n        android:id=\"@+id/manga_reader_toolbar\"\n        style=\"@style/Widget.Material3.Toolbar.Surface\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:minHeight=\"?actionBarSize\"\n        tools:visibility=\"gone\" />\n\n\n    <LinearLayout\n        android:id=\"@+id/manga_reader_bottom_sheet\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom\"\n        android:orientation=\"vertical\">\n\n        <LinearLayout\n            android:id=\"@+id/manga_reader_nav\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_gravity=\"bottom\"\n            android:layout_marginStart=\"8dp\"\n            android:layout_marginEnd=\"8dp\"\n            android:layout_marginBottom=\"16dp\"\n            android:layoutDirection=\"rtl\"\n            android:orientation=\"horizontal\">\n\n            <ImageButton\n                android:id=\"@+id/manga_reader_previous\"\n                android:layout_width=\"48dp\"\n                android:layout_height=\"48dp\"\n                android:contentDescription=\"@string/above_chapter\"\n                android:tooltipText=\"@string/above_chapter\"\n                app:srcCompat=\"@drawable/ic_skip_previous_24\"\n                app:tint=\"?colorOnSurface\" />\n\n            <LinearLayout\n                android:id=\"@+id/manga_reader_seeker\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"match_parent\"\n                android:layout_marginStart=\"8dp\"\n                android:layout_marginEnd=\"8dp\"\n                android:layout_weight=\"1\"\n                android:orientation=\"horizontal\">\n\n                <TextView\n                    android:id=\"@+id/manga_reader_chapter_now_number\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"match_parent\"\n                    android:gravity=\"center\"\n                    android:minWidth=\"32dp\"\n                    android:textColor=\"?colorOnSurface\"\n                    android:textSize=\"15sp\"\n                    tools:text=\"1\" />\n\n                <com.google.android.material.slider.Slider\n                    android:id=\"@+id/manga_reader_slider\"\n                    android:layout_width=\"0dp\"\n                    android:layout_height=\"wrap_content\"\n                    android:layout_weight=\"1\"\n                    android:contentDescription=\"@string/slider_bar_cd\"\n                    android:maxHeight=\"?attr/actionBarSize\"\n                    android:minHeight=\"?attr/actionBarSize\"\n                    android:stepSize=\"1\"\n                    app:tickVisible=\"false\"\n                    tools:ignore=\"NestedWeights\" />\n\n                <TextView\n                    android:id=\"@+id/manga_reader_chapter_total_number\"\n                    android:layout_width=\"wrap_content\"\n                    android:layout_height=\"match_parent\"\n                    android:gravity=\"center\"\n                    android:minWidth=\"32dp\"\n                    android:textColor=\"?colorOnSurface\"\n                    android:textSize=\"15sp\"\n                    tools:text=\"15\" />\n\n            </LinearLayout>\n\n            <ImageButton\n                android:id=\"@+id/manga_reader_next\"\n                android:layout_width=\"48dp\"\n                android:layout_height=\"48dp\"\n                android:contentDescription=\"@string/next_chapter\"\n                android:tooltipText=\"@string/next_chapter\"\n                app:srcCompat=\"@drawable/ic_skip_next_24\"\n                app:tint=\"?colorOnSurface\" />\n\n        </LinearLayout>\n\n        <androidx.constraintlayout.widget.ConstraintLayout\n            android:id=\"@+id/manga_reader_bottom_toolbar\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:background=\"?colorSurface\"\n            android:paddingTop=\"16dp\">\n\n            <TextView\n                android:id=\"@+id/reader_manga_mode_tip\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"16dp\"\n                android:textAppearance=\"?textAppearanceTitleMedium\"\n                app:layout_constraintBottom_toTopOf=\"@+id/guideline3\"\n                app:layout_constraintEnd_toStartOf=\"@+id/manga_reader_setting\"\n                app:layout_constraintStart_toStartOf=\"parent\"\n                tools:text=\"READER MODE\" />\n\n            <TextView\n                android:id=\"@+id/reader_manga_subtitle\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:textAppearance=\"?textAppearanceBodySmall\"\n                app:layout_constraintEnd_toEndOf=\"@+id/reader_manga_mode_tip\"\n                app:layout_constraintStart_toStartOf=\"@+id/reader_manga_mode_tip\"\n                app:layout_constraintTop_toTopOf=\"@+id/guideline3\"\n                tools:text=\"DATE\" />\n\n\n            <ImageButton\n                android:id=\"@+id/manga_reader_setting\"\n                android:layout_width=\"48dp\"\n                android:layout_height=\"48dp\"\n                android:layout_marginEnd=\"16dp\"\n                android:contentDescription=\"@string/setting\"\n                android:tooltipText=\"@string/setting\"\n                app:layout_constraintBottom_toBottomOf=\"parent\"\n                app:layout_constraintEnd_toEndOf=\"parent\"\n                app:layout_constraintTop_toTopOf=\"parent\"\n                app:srcCompat=\"@drawable/ic_setting_outline\"\n                app:tint=\"?colorControlNormal\" />\n\n            <androidx.constraintlayout.widget.Guideline\n                android:id=\"@+id/guideline3\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:orientation=\"horizontal\"\n                app:layout_constraintGuide_percent=\"0.5\" />\n\n        </androidx.constraintlayout.widget.ConstraintLayout>\n\n    </LinearLayout>\n\n    <include\n        android:id=\"@+id/layout_error_include\"\n        layout=\"@layout/layout_error\" />\n\n    <com.google.android.material.progressindicator.CircularProgressIndicator\n        android:id=\"@+id/load_indicator\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"center\"\n        android:indeterminate=\"true\" />\n\n</androidx.coordinatorlayout.widget.CoordinatorLayout>"
  },
  {
    "path": "app/src/main/res/layout/fragment_dialog_download_info.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.core.widget.NestedScrollView 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.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:paddingTop=\"16dp\">\n\n        <com.google.android.material.imageview.ShapeableImageView\n            android:id=\"@+id/download_dialog_indo_image\"\n            android:layout_width=\"150dp\"\n            android:layout_height=\"230dp\"\n            android:layout_marginHorizontal=\"16dp\"\n            android:scaleType=\"centerCrop\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\"\n            app:shapeAppearance=\"@style/RoundStyle\"\n            app:strokeColor=\"?colorControlNormal\"\n            app:strokeWidth=\"1dp\" />\n\n        <com.google.android.material.textview.MaterialTextView\n            android:id=\"@+id/download_dialog_info_name\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginHorizontal=\"16dp\"\n            android:textAppearance=\"?textAppearanceTitleLarge\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toEndOf=\"@+id/download_dialog_indo_image\"\n            app:layout_constraintTop_toTopOf=\"parent\"\n            tools:text=\"漫画名字\" />\n\n        <androidx.recyclerview.widget.RecyclerView\n            android:id=\"@+id/download_dialog_info_recycler_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:layout_marginTop=\"8dp\"\n            android:orientation=\"vertical\"\n            app:layoutManager=\"androidx.recyclerview.widget.LinearLayoutManager\"\n            app:layout_constraintTop_toBottomOf=\"@id/download_dialog_indo_image\" />\n\n    </androidx.constraintlayout.widget.ConstraintLayout>\n\n</androidx.core.widget.NestedScrollView>"
  },
  {
    "path": "app/src/main/res/layout/fragment_reader_normal.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.viewpager2.widget.ViewPager2 xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layoutDirection=\"rtl\"\n    android:background=\"@android:color/black\"\n    android:id=\"@+id/manga_reader_viewpager_2\">\n\n</androidx.viewpager2.widget.ViewPager2>"
  },
  {
    "path": "app/src/main/res/layout/fragment_reader_webtoon.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.shicheeng.copymanga.fm.reader.webtoon.WebtoonScalingFrame xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:id=\"@+id/manga_reader_webtoon_root\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\">\n\n    <com.shicheeng.copymanga.fm.reader.webtoon.WebtoonRecyclerView\n        android:id=\"@+id/manga_reader_webtoon_recyclerview\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:background=\"@android:color/black\"\n        app:layoutManager=\".fm.reader.webtoon.WebtoonLayoutManager\" />\n\n</com.shicheeng.copymanga.fm.reader.webtoon.WebtoonScalingFrame>"
  },
  {
    "path": "app/src/main/res/layout/item_last_page.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    android:background=\"@android:color/black\">\n\n\n    <TextView\n        android:id=\"@+id/page_switch_tip_text\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:textAppearance=\"?textAppearanceTitleMedium\"\n        android:textColor=\"@android:color/white\"\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        tools:text=\"没有下一章了\" />\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_page.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<FrameLayout 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    <com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView\n        android:id=\"@+id/biv_pager\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        app:restoreStrategy=\"deferred\" />\n\n    <include layout=\"@layout/layout_image_load\" />\n\n    <include\n        android:id=\"@+id/error_layout\"\n        layout=\"@layout/layout_error\" />\n\n</FrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/item_page_webtoon.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.shicheeng.copymanga.fm.reader.webtoon.WebtoonFrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\">\n\n    <com.shicheeng.copymanga.fm.reader.webtoon.WebtoonImageView\n        android:id=\"@+id/biv_pager_webtoon\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:panEnabled=\"false\"\n        app:quickScaleEnabled=\"false\"\n        app:zoomEnabled=\"false\"/>\n\n    <include layout=\"@layout/layout_image_load\" />\n\n    <include\n        android:id=\"@+id/error_layout\"\n        layout=\"@layout/layout_error\" />\n\n</com.shicheeng.copymanga.fm.reader.webtoon.WebtoonFrameLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_error.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:id=\"@+id/error_text_layout\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\"\n    android:layout_gravity=\"center\"\n    android:visibility=\"gone\"\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    tools:visibility=\"visible\">\n\n    <TextView\n        android:id=\"@+id/error_text_tip\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/error\"\n        android:textAppearance=\"?textAppearanceTitleMedium\"\n        android:textColor=\"?colorOnSurfaceInverse\"\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\n    <TextView\n        android:id=\"@+id/error_text_tip_desc\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"@string/error_non_text\"\n        android:textAppearance=\"?textAppearanceBodyMedium\"\n        android:textColor=\"?colorOnSurfaceInverse\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/error_text_tip\" />\n\n    <com.google.android.material.button.MaterialButton\n        android:id=\"@+id/btn_error_retry\"\n        style=\"@style/Widget.Material3.Button.TonalButton\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"16dp\"\n        android:text=\"@string/retry\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@+id/error_text_tip_desc\" />\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_image_load.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<merge xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    tools:parentTag=\"android.widget.FrameLayout\">\n\n    <com.google.android.material.progressindicator.CircularProgressIndicator\n        android:layout_height=\"wrap_content\"\n        android:layout_width=\"wrap_content\"\n        android:indeterminate=\"true\"\n        android:id=\"@+id/load_indicator\"\n        android:layout_gravity=\"center\"/>\n\n</merge>"
  },
  {
    "path": "app/src/main/res/layout/layout_setting_wraning_region.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout 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=\"wrap_content\"\n    android:clipToPadding=\"true\"\n    android:gravity=\"center\"\n    android:minHeight=\"?android:attr/listPreferredItemHeightSmall\"\n    android:orientation=\"horizontal\"\n\n    android:paddingStart=\"?android:attr/listPreferredItemPaddingStart\"\n    android:paddingEnd=\"?android:attr/listPreferredItemPaddingEnd\">\n\n    <include\n        layout=\"@layout/image_frame\"\n        tools:ignore=\"PrivateResource\" />\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"8dp\"\n        android:layout_marginBottom=\"8dp\"\n        android:drawablePadding=\"8dp\"\n        android:text=\"@string/use_forgin_region_tip\"\n        android:textAppearance=\"?textAppearanceBodyMedium\"\n        app:drawableStartCompat=\"@drawable/ic_manga_info_main\" />\n\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/layout_widget_switch_pref.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<com.google.android.material.switchmaterial.SwitchMaterial xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:id=\"@+id/switchWidget\"\n    style=\"@style/Widget.Material3.CompoundButton.MaterialSwitch\"\n    android:layout_width=\"wrap_content\"\n    android:layout_height=\"wrap_content\">\n\n</com.google.android.material.switchmaterial.SwitchMaterial>"
  },
  {
    "path": "app/src/main/res/layout/magan_select_bar.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout 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=\"wrap_content\"\n    android:layout_marginHorizontal=\"16dp\"\n    android:layout_marginVertical=\"4dp\"\n    android:gravity=\"center\"\n    android:orientation=\"horizontal\">\n\n    <TextView\n        android:id=\"@+id/select_bar_text\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:text=\"@string/order\"\n        android:textAppearance=\"?textAppearanceTitleLarge\" />\n\n    <com.google.android.material.textfield.TextInputLayout\n        android:id=\"@+id/select_bar_expand_menu\"\n        style=\"@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"1\"\n        android:hint=\"@string/order\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"@+id/guideline2\"\n        app:layout_constraintTop_toBottomOf=\"@+id/menu_sort\">\n\n        <AutoCompleteTextView\n            android:id=\"@+id/auto_2\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:inputType=\"none\"\n            tools:ignore=\"LabelFor\" />\n\n    </com.google.android.material.textfield.TextInputLayout>\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/manga_headline_1.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    android:orientation=\"horizontal\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:clickable=\"true\"\n    android:background=\"?android:attr/selectableItemBackground\"\n    android:foreground=\"?attr/selectableItemBackgroundBorderless\"\n    android:id=\"@+id/linear_id\"\n    android:padding=\"12dp\">\n\n    <TextView\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_weight=\"4\"\n        android:id=\"@+id/title_id\"\n        android:maxLines=\"1\"\n        android:ellipsize=\"end\"\n        android:text=\"@string/app_name\"\n        android:textAppearance=\"?textAppearanceTitleLarge\"/>\n\n    <ImageView\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"match_parent\"\n        android:layout_weight=\"1\"\n        android:layout_gravity=\"end\"\n        android:src=\"@drawable/ic_look_more\"\n        app:tint=\"?colorPrimary\"\n        android:contentDescription=\"@string/todo\" />\n\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/sheet_manga_model_switcher.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    <TextView\n        android:id=\"@+id/change_mode_text\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        android:layout_margin=\"16dp\"\n        android:text=\"@string/reader_mode_tip\"\n        android:textAppearance=\"?textAppearanceTitleSmall\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <FrameLayout\n        android:id=\"@+id/manga_reader_bottom_mode_select\"\n        android:layout_width=\"0dp\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintEnd_toEndOf=\"parent\"\n        app:layout_constraintStart_toStartOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/change_mode_text\">\n\n        <com.google.android.material.button.MaterialButtonToggleGroup\n            android:id=\"@+id/reader_switchers_group\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:layout_marginHorizontal=\"16dp\"\n            android:layout_marginVertical=\"8dp\"\n            android:baselineAligned=\"false\"\n            android:orientation=\"horizontal\"\n            app:selectionRequired=\"true\"\n            app:singleSelection=\"true\">\n\n            <com.google.android.material.button.MaterialButton\n                android:id=\"@+id/reader_switcher_to_horizontal\"\n                style=\"@style/Widget.CopyManga.ToggleButton.Vertical\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"8dp\"\n                android:layout_weight=\"1\"\n                android:text=\"@string/korea_chinese_top_to_bottom\"\n                app:icon=\"@drawable/ic_swith_vert\" />\n\n            <com.google.android.material.button.MaterialButton\n                android:id=\"@+id/reader_switcher_to_vert\"\n                style=\"@style/Widget.CopyManga.ToggleButton.Vertical\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"8dp\"\n                android:layout_weight=\"1\"\n                android:text=\"@string/japanese_r_to_l\"\n                app:icon=\"@drawable/ic_swith_horiz\" />\n\n            <com.google.android.material.button.MaterialButton\n                android:id=\"@+id/reader_switcher_to_l_to_r\"\n                style=\"@style/Widget.CopyManga.ToggleButton.Vertical\"\n                android:layout_width=\"0dp\"\n                android:layout_height=\"wrap_content\"\n                android:layout_marginStart=\"8dp\"\n                android:layout_weight=\"1\"\n                android:text=\"@string/manga_mode_l_t_r\"\n                app:icon=\"@drawable/ic_swith_horiz\" />\n\n        </com.google.android.material.button.MaterialButtonToggleGroup>\n\n    </FrameLayout>\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_copy.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=\"@color/ic_copy_background\"/>\n    <foreground android:drawable=\"@mipmap/ic_copy_foreground\" />\n    <monochrome android:drawable=\"@mipmap/ic_copy_foreground\"/>\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/resources.properties",
    "content": "unqualifiedResLocale=en-US"
  },
  {
    "path": "app/src/main/res/values/about_libraries.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources />"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<resources>\n    <color name=\"md_theme_primary\">#3C6090</color>\n    <color name=\"md_theme_onPrimary\">#FFFFFF</color>\n    <color name=\"md_theme_primaryContainer\">#D4E3FF</color>\n    <color name=\"md_theme_onPrimaryContainer\">#001C3A</color>\n    <color name=\"md_theme_secondary\">#545F71</color>\n    <color name=\"md_theme_onSecondary\">#FFFFFF</color>\n    <color name=\"md_theme_secondaryContainer\">#D8E3F8</color>\n    <color name=\"md_theme_onSecondaryContainer\">#111C2B</color>\n    <color name=\"md_theme_tertiary\">#6D5676</color>\n    <color name=\"md_theme_onTertiary\">#FFFFFF</color>\n    <color name=\"md_theme_tertiaryContainer\">#F7D8FF</color>\n    <color name=\"md_theme_onTertiaryContainer\">#271430</color>\n    <color name=\"md_theme_error\">#BA1A1A</color>\n    <color name=\"md_theme_onError\">#FFFFFF</color>\n    <color name=\"md_theme_errorContainer\">#FFDAD6</color>\n    <color name=\"md_theme_onErrorContainer\">#410002</color>\n    <color name=\"md_theme_background\">#F9F9FF</color>\n    <color name=\"md_theme_onBackground\">#191C20</color>\n    <color name=\"md_theme_surface\">#F9F9FF</color>\n    <color name=\"md_theme_onSurface\">#191C20</color>\n    <color name=\"md_theme_surfaceVariant\">#E0E2EC</color>\n    <color name=\"md_theme_onSurfaceVariant\">#43474E</color>\n    <color name=\"md_theme_outline\">#74777F</color>\n    <color name=\"md_theme_outlineVariant\">#C3C6CF</color>\n    <color name=\"md_theme_scrim\">#000000</color>\n    <color name=\"md_theme_inverseSurface\">#2E3035</color>\n    <color name=\"md_theme_inverseOnSurface\">#F0F0F7</color>\n    <color name=\"md_theme_inversePrimary\">#A5C8FF</color>\n    <color name=\"md_theme_primaryFixed\">#D4E3FF</color>\n    <color name=\"md_theme_onPrimaryFixed\">#001C3A</color>\n    <color name=\"md_theme_primaryFixedDim\">#A5C8FF</color>\n    <color name=\"md_theme_onPrimaryFixedVariant\">#224876</color>\n    <color name=\"md_theme_secondaryFixed\">#D8E3F8</color>\n    <color name=\"md_theme_onSecondaryFixed\">#111C2B</color>\n    <color name=\"md_theme_secondaryFixedDim\">#BCC7DC</color>\n    <color name=\"md_theme_onSecondaryFixedVariant\">#3D4758</color>\n    <color name=\"md_theme_tertiaryFixed\">#F7D8FF</color>\n    <color name=\"md_theme_onTertiaryFixed\">#271430</color>\n    <color name=\"md_theme_tertiaryFixedDim\">#DABDE2</color>\n    <color name=\"md_theme_onTertiaryFixedVariant\">#553F5D</color>\n    <color name=\"md_theme_surfaceDim\">#D9DAE0</color>\n    <color name=\"md_theme_surfaceBright\">#F9F9FF</color>\n    <color name=\"md_theme_surfaceContainerLowest\">#FFFFFF</color>\n    <color name=\"md_theme_surfaceContainerLow\">#F2F3FA</color>\n    <color name=\"md_theme_surfaceContainer\">#EDEDF4</color>\n    <color name=\"md_theme_surfaceContainerHigh\">#E7E8EE</color>\n    <color name=\"md_theme_surfaceContainerHighest\">#E1E2E9</color>\n    <color name=\"md_theme_primary_mediumContrast\">#1D4472</color>\n    <color name=\"md_theme_onPrimary_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_primaryContainer_mediumContrast\">#5376A7</color>\n    <color name=\"md_theme_onPrimaryContainer_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondary_mediumContrast\">#394354</color>\n    <color name=\"md_theme_onSecondary_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondaryContainer_mediumContrast\">#6B7588</color>\n    <color name=\"md_theme_onSecondaryContainer_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiary_mediumContrast\">#513B59</color>\n    <color name=\"md_theme_onTertiary_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiaryContainer_mediumContrast\">#856C8D</color>\n    <color name=\"md_theme_onTertiaryContainer_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_error_mediumContrast\">#8C0009</color>\n    <color name=\"md_theme_onError_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_errorContainer_mediumContrast\">#DA342E</color>\n    <color name=\"md_theme_onErrorContainer_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_background_mediumContrast\">#F9F9FF</color>\n    <color name=\"md_theme_onBackground_mediumContrast\">#191C20</color>\n    <color name=\"md_theme_surface_mediumContrast\">#F9F9FF</color>\n    <color name=\"md_theme_onSurface_mediumContrast\">#191C20</color>\n    <color name=\"md_theme_surfaceVariant_mediumContrast\">#E0E2EC</color>\n    <color name=\"md_theme_onSurfaceVariant_mediumContrast\">#3F434A</color>\n    <color name=\"md_theme_outline_mediumContrast\">#5B5F67</color>\n    <color name=\"md_theme_outlineVariant_mediumContrast\">#777B83</color>\n    <color name=\"md_theme_scrim_mediumContrast\">#000000</color>\n    <color name=\"md_theme_inverseSurface_mediumContrast\">#2E3035</color>\n    <color name=\"md_theme_inverseOnSurface_mediumContrast\">#F0F0F7</color>\n    <color name=\"md_theme_inversePrimary_mediumContrast\">#A5C8FF</color>\n    <color name=\"md_theme_primaryFixed_mediumContrast\">#5376A7</color>\n    <color name=\"md_theme_onPrimaryFixed_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_primaryFixedDim_mediumContrast\">#395D8D</color>\n    <color name=\"md_theme_onPrimaryFixedVariant_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondaryFixed_mediumContrast\">#6B7588</color>\n    <color name=\"md_theme_onSecondaryFixed_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondaryFixedDim_mediumContrast\">#525C6E</color>\n    <color name=\"md_theme_onSecondaryFixedVariant_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiaryFixed_mediumContrast\">#856C8D</color>\n    <color name=\"md_theme_onTertiaryFixed_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiaryFixedDim_mediumContrast\">#6B5474</color>\n    <color name=\"md_theme_onTertiaryFixedVariant_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_surfaceDim_mediumContrast\">#D9DAE0</color>\n    <color name=\"md_theme_surfaceBright_mediumContrast\">#F9F9FF</color>\n    <color name=\"md_theme_surfaceContainerLowest_mediumContrast\">#FFFFFF</color>\n    <color name=\"md_theme_surfaceContainerLow_mediumContrast\">#F2F3FA</color>\n    <color name=\"md_theme_surfaceContainer_mediumContrast\">#EDEDF4</color>\n    <color name=\"md_theme_surfaceContainerHigh_mediumContrast\">#E7E8EE</color>\n    <color name=\"md_theme_surfaceContainerHighest_mediumContrast\">#E1E2E9</color>\n    <color name=\"md_theme_primary_highContrast\">#002246</color>\n    <color name=\"md_theme_onPrimary_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_primaryContainer_highContrast\">#1D4472</color>\n    <color name=\"md_theme_onPrimaryContainer_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondary_highContrast\">#182332</color>\n    <color name=\"md_theme_onSecondary_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondaryContainer_highContrast\">#394354</color>\n    <color name=\"md_theme_onSecondaryContainer_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiary_highContrast\">#2E1A37</color>\n    <color name=\"md_theme_onTertiary_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiaryContainer_highContrast\">#513B59</color>\n    <color name=\"md_theme_onTertiaryContainer_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_error_highContrast\">#4E0002</color>\n    <color name=\"md_theme_onError_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_errorContainer_highContrast\">#8C0009</color>\n    <color name=\"md_theme_onErrorContainer_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_background_highContrast\">#F9F9FF</color>\n    <color name=\"md_theme_onBackground_highContrast\">#191C20</color>\n    <color name=\"md_theme_surface_highContrast\">#F9F9FF</color>\n    <color name=\"md_theme_onSurface_highContrast\">#000000</color>\n    <color name=\"md_theme_surfaceVariant_highContrast\">#E0E2EC</color>\n    <color name=\"md_theme_onSurfaceVariant_highContrast\">#20242B</color>\n    <color name=\"md_theme_outline_highContrast\">#3F434A</color>\n    <color name=\"md_theme_outlineVariant_highContrast\">#3F434A</color>\n    <color name=\"md_theme_scrim_highContrast\">#000000</color>\n    <color name=\"md_theme_inverseSurface_highContrast\">#2E3035</color>\n    <color name=\"md_theme_inverseOnSurface_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_inversePrimary_highContrast\">#E4ECFF</color>\n    <color name=\"md_theme_primaryFixed_highContrast\">#1D4472</color>\n    <color name=\"md_theme_onPrimaryFixed_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_primaryFixedDim_highContrast\">#002D58</color>\n    <color name=\"md_theme_onPrimaryFixedVariant_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondaryFixed_highContrast\">#394354</color>\n    <color name=\"md_theme_onSecondaryFixed_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_secondaryFixedDim_highContrast\">#232D3D</color>\n    <color name=\"md_theme_onSecondaryFixedVariant_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiaryFixed_highContrast\">#513B59</color>\n    <color name=\"md_theme_onTertiaryFixed_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_tertiaryFixedDim_highContrast\">#392542</color>\n    <color name=\"md_theme_onTertiaryFixedVariant_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_surfaceDim_highContrast\">#D9DAE0</color>\n    <color name=\"md_theme_surfaceBright_highContrast\">#F9F9FF</color>\n    <color name=\"md_theme_surfaceContainerLowest_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_surfaceContainerLow_highContrast\">#F2F3FA</color>\n    <color name=\"md_theme_surfaceContainer_highContrast\">#EDEDF4</color>\n    <color name=\"md_theme_surfaceContainerHigh_highContrast\">#E7E8EE</color>\n    <color name=\"md_theme_surfaceContainerHighest_highContrast\">#E1E2E9</color>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/day_night_01.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <attr  format=\"color\" name=\"barColor\"/>\n    <attr format=\"color\" name=\"textColorMe\"/>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values/expand_view_declare.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"ExpandSelectionBar\">\n        <attr name=\"tipText\" format=\"string\" />\n        <attr name=\"hintText\" format=\"string\" />\n    </declare-styleable>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values/head_line_view.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <declare-styleable name=\"HeadLineView\">\n        <attr name=\"headTitle\" format=\"string\"/>\n    </declare-styleable>\n\n    <declare-styleable name=\"HeadLineViewChapter\">\n        <attr name=\"headChapterTitle\" format=\"string\" />\n\n    </declare-styleable>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values/ic_copy_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"ic_copy_background\">#2A85C6</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/ic_launcher_copy_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources></resources>"
  },
  {
    "path": "app/src/main/res/values/inch.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources></resources>"
  },
  {
    "path": "app/src/main/res/values/string_array.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string-array name=\"orientation_array\">\n        <item>@string/japanese_r_to_l</item>\n        <item>@string/korea_chinese_top_to_bottom</item>\n        <item>@string/manga_mode_l_t_r</item>\n    </string-array>\n\n    <string-array name=\"api_header\">\n        <item>copymanga.org</item>\n        <item>copymanga.info</item>\n        <item>copymanga.net</item>\n        <item>copymanga.site</item>\n    </string-array>\n\n    <string-array name=\"api_header_value\">\n        <item>copymanga.org</item>\n        <item>copymanga.info</item>\n        <item>copymanga.net</item>\n        <item>copymanga.site</item>\n    </string-array>\n\n</resources>"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<!--特别注意这些都是机器翻译和自己中文化英语翻译-->\n<!--Pay special attention to these are machine translations and author's Chinglish translations.-->\n<resources>\n    <string name=\"app_name\">ShariganManga</string>\n    <string name=\"recommend\">Recommend</string>\n    <string name=\"day_rank\">Day</string>\n    <string name=\"comic_rank\">Comic Rank</string>\n    <string name=\"month_rank\">Month</string>\n    <string name=\"week_rank\">Week</string>\n    <string name=\"all_rank\">Total</string>\n    <string name=\"hot_manga\">Hot</string>\n    <string name=\"new_manga\">New</string>\n    <string name=\"finish_manga\">Finish</string>\n    <string name=\"todo\" translatable=\"false\">TODO</string>\n    <string name=\"chapter\">%s Chapters</string>\n    <string name=\"theme\">Theme</string>\n    <string name=\"order\">Order</string>\n    <string name=\"error\">Something Error</string>\n    <string name=\"retry\">Retry</string>\n    <string name=\"next_chapter\">Next chapter</string>\n    <string name=\"about\">About</string>\n    <string name=\"search_text\">Search…</string>\n    <string name=\"history\">History</string>\n    <string name=\"error_non_text\">No input text</string>\n    <string name=\"touch_to_retry\">Touch to retry</string>\n    <string name=\"explore\">Explore</string>\n    <string name=\"load_failure\">Load failure</string>\n    <string name=\"all_clear\">All clear</string>\n    <string name=\"above_chapter\">Above chapter</string>\n    <string name=\"slider_bar_cd\">slider bar that show pager number</string>\n    <string name=\"no_history\">History is empty</string>\n    <string name=\"japanese_r_to_l\">Reader mode: right to left</string>\n    <string name=\"korea_chinese_top_to_bottom\">Reader model: webtoon</string>\n    <string name=\"pref_main\">Main</string>\n    <string name=\"pref_orintation\">Prefer orientation</string>\n    <string name=\"perf_about\">About project</string>\n    <string name=\"pref_app\">Project</string>\n    <string name=\"pref_app_summary\">Look at this app github website</string>\n    <string name=\"pref_about_summary\">Look app info and LICENSE</string>\n    <string name=\"use_forgin_region\">Use foreign api</string>\n    <string name=\"use_forgin_region_summary\">Use the foreign api for request</string>\n    <string name=\"use_forgin_region_tip\">Tip: whatever api do you use, only the image CDN will change</string>\n    <string name=\"setting\">Setting</string>\n    <string name=\"last_update\">Last update in %s</string>\n    <string name=\"download_channel_name\">Download Manga</string>\n    <string name=\"manga_download_get_ready\">Download prepare</string>\n    <string name=\"system\">System</string>\n    <string name=\"clear_cache\">Clear cache</string>\n    <string name=\"cache_used\">%s of internal storage is used by cache</string>\n    <string name=\"clear_pager_cache\">Clear pager cache</string>\n    <string name=\"error_in_download\">Download error</string>\n    <string name=\"downloading\">Downloading</string>\n    <string name=\"waiting\">Waiting</string>\n    <string name=\"all_done\">All done!</string>\n    <string name=\"cancel\">Cancelled</string>\n    <string name=\"items_downloaded\">%s Items</string>\n    <string name=\"post_before_done\">In process of post-before-done</string>\n    <string name=\"perpare_to_finish\">Prepare to finish</string>\n    <string name=\"download_manga\">Download</string>\n    <string name=\"see_the_download\">See the downloading content</string>\n    <string name=\"manga_mode_l_t_r\">Reader mode: left to right</string>\n    <string name=\"reader_mode_tip\">Select the Reader mode</string>\n    <string name=\"local\">Local</string>\n    <string name=\"in_loading_next_chapter\">Loading chapter</string>\n    <string name=\"chapter_page_indicator\" translatable=\"false\">%d / %d</string>\n    <string name=\"personal\">Personal</string>\n    <string name=\"quick_touch\">Quick touch</string>\n    <string name=\"quick_touch_summary\">Tap the bottom of srceen to scroll page</string>\n    <string name=\"new_version\">New version was found</string>\n    <string name=\"update\">Update</string>\n    <string name=\"website_look\">Website</string>\n    <string name=\"disable_update_detect\">Disable detect new version</string>\n    <string name=\"disable_update_summary\">Maybe miss some important fixes</string>\n    <string name=\"home_des\">Home</string>\n    <string name=\"select_api_header\">Select api header</string>\n    <string name=\"top\">Region</string>\n    <string name=\"rank_mini\">Rank</string>\n    <string name=\"trend_up\">Trend up</string>\n    <string name=\"default_select\">No select</string>\n    <string name=\"no_alias\">No alias</string>\n    <string name=\"manga_info_collapse\">Collapse</string>\n    <string name=\"manga_info_expand\">Expand</string>\n    <string name=\"no_description\">No description</string>\n    <string name=\"manga_detail\">Detail</string>\n    <string name=\"back_to_up\">Navigate up</string>\n    <string name=\"chapters_list\">List</string>\n    <string name=\"preparing\">Preparing</string>\n    <string name=\"empty_download\">Downloads is empty</string>\n    <string name=\"download_first_5\">Download the first five chapters</string>\n    <string name=\"download_all\">Download all chapters</string>\n    <string name=\"download_last_5\">Download the last five chapters</string>\n    <string name=\"exit_select_mode\">Exit selection mode</string>\n    <string name=\"switch_api_dialog_summary\">Select a URL host, and you need to refresh the data after switching to see the effect. Under normal circumstances, if you are not sure that it is the official reason but it cannot be loaded, you can try to switch.</string>\n    <string name=\"swith_reader_mode_dialog_summary\">Toggle reading mode. Under normal circumstances, if you have set the reading mode while watching the manga, then this option will not affect the set manga.</string>\n    <string name=\"close_search_dock\">Close search dock</string>\n    <string name=\"input_the_word\">Type search</string>\n    <string name=\"subscribe_for_updates\">Subscribe for updates</string>\n    <string name=\"unsubscribe_for_updates\">Unsubscribe for updates</string>\n    <string name=\"enable\">enable</string>\n    <string name=\"not_enabled\">Not enabled</string>\n    <string name=\"enable_update_text\">Do you need to enable scheduled updates? This will refresh the manga at a specific time, you can manually turn it off in the settings. If not enabled you can refresh manually.</string>\n    <string name=\"confrim_update\">Regularly update comics?</string>\n    <string name=\"subscribe_for_updates_summary\">After it is turned on, it will try to detect whether the manga is updated at a fixed time</string>\n    <string name=\"see_all\">Look all</string>\n    <string name=\"subscribe\">Subscribe</string>\n    <string name=\"copy_manga_summary\">A third-party app for Copy Manga with Material You features</string>\n    <string name=\"open_source\">Open source</string>\n    <string name=\"update_manga\">Update manga</string>\n    <string name=\"completed\">Completed</string>\n    <string name=\"input\">Input</string>\n    <string name=\"time_detect\">Detection interval (hours)</string>\n    <string name=\"time_detect_summary\">Enter the detection interval. In order to avoid the server from detecting third-party requests due to excessive throughput, it is recommended that the interval be as long as possible.</string>\n    <string name=\"only_wifi\">In wifi</string>\n    <string name=\"only_charging\">In charging</string>\n    <string name=\"low_power\">In low power</string>\n    <string name=\"update_constant\">Update constants</string>\n    <string name=\"update_constant_support_text\">Set the conditions when updating</string>\n    <string name=\"work_information\">Work Information</string>\n    <string name=\"work_info_summary\">View information about the worker used by the application</string>\n    <string name=\"successed\">Successes</string>\n    <string name=\"running\">Running</string>\n    <string name=\"enqueue\">Enqueue</string>\n    <string name=\"no_select_constants\">No select constants</string>\n    <string name=\"read_in\">• Read in %d</string>\n    <string name=\"refresh\">Manual refresh</string>\n    <string name=\"continue_read\">Continue read</string>\n    <string name=\"start_read\">Start read</string>\n    <string name=\"search_is_empty\">Search is empty</string>\n    <string name=\"info_read_in\">Read Chapter %d, Page %d</string>\n    <string name=\"theme_mode\">Theme Mode</string>\n    <string name=\"theme_light\">Light</string>\n    <string name=\"theme_dark\">Dark</string>\n    <string name=\"theme_with_system\">System</string>\n    <string name=\"theme_mode_support_text\">Select the system theme mode, and \"System\" will become useless on some systems that do not have a \"night mode\" themselves.</string>\n    <string name=\"cut_out_display\">Display content in the notch area</string>\n    <string name=\"no_next_chapetr\">No next chapter</string>\n    <string name=\"no_privous_chapter\">No previous chapter</string>\n    <string name=\"cut_out_display_summary\">It is recommended to turn it on. If you turn it off, the notch area will be displayed in black</string>\n    <string name=\"tip_subscribe\">Note: If your phone is more aggressive about backend management, it may not update.</string>\n    <string name=\"delete\">Delete</string>\n    <string name=\"topic\">Topic</string>\n    <string name=\"topic_detail_text\">Topic details</string>\n    <string name=\"cache_size_setting\">Cache size</string>\n    <string name=\"cache_size_setting_supporting_text\">Set the maximum cache size generated gor reading (MB)</string>\n    <string name=\"read_finished\">• Finished</string>\n    <string name=\"mark_to_read\">Mark to read</string>\n    <string name=\"mark_to_no_read\">Mark to no read</string>\n    <string name=\"no_content\">No content</string>\n    <string name=\"login_text\">Login</string>\n    <string name=\"user_name_text\">Username</string>\n    <string name=\"password_text\">Password</string>\n    <string name=\"no_login\">No login</string>\n    <string name=\"login_personal\">User</string>\n    <string name=\"shelf_cloud\">Clouded lib</string>\n    <string name=\"local_history\">Local history</string>\n    <string name=\"web_history\">Web history</string>\n    <string name=\"re_login\">Re-register</string>\n    <string name=\"gender\">Gender</string>\n    <string name=\"nickname_text\">nickname</string>\n    <string name=\"fatal_error\">Fatal error</string>\n    <string name=\"try_to_send_to_me\">Please try to send to the author</string>\n    <string name=\"send\">Send</string>\n    <string name=\"finish_this\">End</string>\n    <string name=\"add\">Add</string>\n    <string name=\"personal_info\">Personal information</string>\n    <string name=\"author_choice\">Choose author</string>\n    <string name=\"author_combine\">Total %s authors</string>\n    <string name=\"authors_manga\">Author Mangas</string>\n    <string name=\"web_point_enable\">Use web reading point</string>\n    <string name=\"web_point_enable_summary\">Start watching from your web browsing history</string>\n    <string name=\"comment_text\">Comment</string>\n    <string name=\"login_expired\">Login status is expired</string>\n    <string name=\"login_failure\">Login failure</string>\n    <string name=\"web_point_warning\">I don\\'t know if this feature is stable. If this option affects viewing, it is recommended to turn it off.</string>\n    <string name=\"web_point_tip\">Note: If you are not logged in or your login has expired, local records will be used.</string>\n    <string name=\"add_to_lib\">Add to bookshelf</string>\n    <string name=\"remove_add_to_lib\">Remove from bookshelf</string>\n    <string name=\"type_send_content\">Enter content…</string>\n    <string name=\"send_comment_bar_title\">Send comment</string>\n    <string name=\"comic_comment_title\">Comic Comment</string>\n    <string name=\"search_result\">Search Result</string>\n    <string name=\"send_comment\">发送</string>\n    <string name=\"pause\">Pause</string>\n    <string name=\"resume\">Resume</string>\n    <string name=\"only_on_wifi\">Download comics only under Wi-Fi</string>\n    <string name=\"only_on_wifi_summary\">After turning on, downloading comics will only be downloaded under WI-FI</string>\n    <string name=\"failure_download\">Downloaded failure</string>\n    <string name=\"prerequisites_miss\">Prerequisites miss</string>\n    <string name=\"thankful_app\">Source of inspiration</string>\n    <string name=\"general_warning\">This open source software will not be responsible for any content in the software</string>\n    <string name=\"general_tips\">Manga chapters, manga pictures, and other mangas data are provided by CopyManga Official</string>\n    <string name=\"download_list\">Download list</string>\n    <string name=\"disclaimer\">免责声明</string>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/style.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <style name=\"Widget.CopyManga.Switch.Perf\" parent=\"Preference.SwitchPreferenceCompat.Material\">\n        <item name=\"widgetLayout\">@layout/layout_widget_switch_pref</item>\n    </style>\n\n    <style name=\"Widget.CopyManga.Dialog.Perf\" parent=\"Preference.DialogPreference.Material\">\n\n    </style>\n\n    <style name=\"Widget.CopyManga.Perf\" parent=\"Preference.Material\" />\n\n    <style name=\"RoundStyle\">\n        <item name=\"cornerFamily\">rounded</item>\n        <item name=\"cornerSize\">8dp</item>\n    </style>\n\n    <style name=\"AppTheme.MyOldAlertDialog\" parent=\"ThemeOverlay.Material3.MaterialAlertDialog\">\n        <item name=\"dialogCornerRadius\">28dp</item>\n        <item name=\"cornerFamily\">rounded</item>\n        <item name=\"android:colorBackground\">?attr/colorSurface</item>\n        <item name=\"android:layout\">@layout/m3_alert_dialog</item>\n    </style>\n\n    <style name=\"Widget.CopyManga.ToggleButton\" parent=\"Widget.Material3.Button.OutlinedButton\">\n        <item name=\"android:checkable\">true</item>\n        <item name=\"android:textAlignment\">textStart</item>\n        <item name=\"iconPadding\">16dp</item>\n    </style>\n\n    <style name=\"Widget.CopyManga.ToggleButton.Vertical\">\n        <item name=\"android:textAlignment\">center</item>\n        <item name=\"iconPadding\">2dp</item>\n        <item name=\"android:singleLine\">false</item>\n        <item name=\"android:lines\">2</item>\n        <item name=\"android:maxLines\">2</item>\n        <item name=\"iconGravity\">top</item>\n        <item name=\"android:paddingTop\">12dp</item>\n        <item name=\"android:paddingBottom\">10dp</item>\n        <item name=\"android:paddingStart\">6dp</item>\n        <item name=\"android:paddingEnd\">6dp</item>\n        <item name=\"android:elegantTextHeight\">false</item>\n        <item name=\"shapeAppearance\">?shapeAppearanceCornerMedium</item>\n    </style>\n\n    <style name=\"Widget.CopyManga.Chip\" parent=\"Widget.Material3.Chip.Suggestion\">\n        <item name=\"chipSurfaceColor\">?attr/colorSurface</item>\n        <item name=\"android:textColor\">?attr/colorOnSurfaceVariant</item>\n        <item name=\"strokeColor\">?attr/colorOutline</item>\n        <item name=\"rippleColor\">?attr/colorControlHighlight</item>\n\n        <!-- Custom chip states -->\n        <item name=\"android:clickable\">true</item>\n        <item name=\"android:focusable\">true</item>\n\n        <!-- Smaller text/height -->\n        <item name=\"chipMinHeight\">28dp</item>\n\n        <!-- Collapse horizontal margin -->\n        <item name=\"chipMinTouchTargetSize\">28dp</item>\n    </style>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/theme_overlays.xml",
    "content": "<resources>\n    <style name=\"ThemeOverlay.AppTheme.MediumContrast\" parent=\"Theme.Material3.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/md_theme_primary_mediumContrast</item>\n        <item name=\"colorOnPrimary\">@color/md_theme_onPrimary_mediumContrast</item>\n        <item name=\"colorPrimaryContainer\">@color/md_theme_primaryContainer_mediumContrast</item>\n        <item name=\"colorOnPrimaryContainer\">@color/md_theme_onPrimaryContainer_mediumContrast</item>\n        <item name=\"colorSecondary\">@color/md_theme_secondary_mediumContrast</item>\n        <item name=\"colorOnSecondary\">@color/md_theme_onSecondary_mediumContrast</item>\n        <item name=\"colorSecondaryContainer\">@color/md_theme_secondaryContainer_mediumContrast</item>\n        <item name=\"colorOnSecondaryContainer\">@color/md_theme_onSecondaryContainer_mediumContrast</item>\n        <item name=\"colorTertiary\">@color/md_theme_tertiary_mediumContrast</item>\n        <item name=\"colorOnTertiary\">@color/md_theme_onTertiary_mediumContrast</item>\n        <item name=\"colorTertiaryContainer\">@color/md_theme_tertiaryContainer_mediumContrast</item>\n        <item name=\"colorOnTertiaryContainer\">@color/md_theme_onTertiaryContainer_mediumContrast</item>\n        <item name=\"colorError\">@color/md_theme_error_mediumContrast</item>\n        <item name=\"colorOnError\">@color/md_theme_onError_mediumContrast</item>\n        <item name=\"colorErrorContainer\">@color/md_theme_errorContainer_mediumContrast</item>\n        <item name=\"colorOnErrorContainer\">@color/md_theme_onErrorContainer_mediumContrast</item>\n        <item name=\"android:colorBackground\">@color/md_theme_background_mediumContrast</item>\n        <item name=\"colorOnBackground\">@color/md_theme_onBackground_mediumContrast</item>\n        <item name=\"colorSurface\">@color/md_theme_surface_mediumContrast</item>\n        <item name=\"colorOnSurface\">@color/md_theme_onSurface_mediumContrast</item>\n        <item name=\"colorSurfaceVariant\">@color/md_theme_surfaceVariant_mediumContrast</item>\n        <item name=\"colorOnSurfaceVariant\">@color/md_theme_onSurfaceVariant_mediumContrast</item>\n        <item name=\"colorOutline\">@color/md_theme_outline_mediumContrast</item>\n        <item name=\"colorOutlineVariant\">@color/md_theme_outlineVariant_mediumContrast</item>\n        <item name=\"colorSurfaceInverse\">@color/md_theme_inverseSurface_mediumContrast</item>\n        <item name=\"colorOnSurfaceInverse\">@color/md_theme_inverseOnSurface_mediumContrast</item>\n        <item name=\"colorPrimaryInverse\">@color/md_theme_inversePrimary_mediumContrast</item>\n        <item name=\"colorPrimaryFixed\">@color/md_theme_primaryFixed_mediumContrast</item>\n        <item name=\"colorOnPrimaryFixed\">@color/md_theme_onPrimaryFixed_mediumContrast</item>\n        <item name=\"colorPrimaryFixedDim\">@color/md_theme_primaryFixedDim_mediumContrast</item>\n        <item name=\"colorOnPrimaryFixedVariant\">@color/md_theme_onPrimaryFixedVariant_mediumContrast</item>\n        <item name=\"colorSecondaryFixed\">@color/md_theme_secondaryFixed_mediumContrast</item>\n        <item name=\"colorOnSecondaryFixed\">@color/md_theme_onSecondaryFixed_mediumContrast</item>\n        <item name=\"colorSecondaryFixedDim\">@color/md_theme_secondaryFixedDim_mediumContrast</item>\n        <item name=\"colorOnSecondaryFixedVariant\">@color/md_theme_onSecondaryFixedVariant_mediumContrast</item>\n        <item name=\"colorTertiaryFixed\">@color/md_theme_tertiaryFixed_mediumContrast</item>\n        <item name=\"colorOnTertiaryFixed\">@color/md_theme_onTertiaryFixed_mediumContrast</item>\n        <item name=\"colorTertiaryFixedDim\">@color/md_theme_tertiaryFixedDim_mediumContrast</item>\n        <item name=\"colorOnTertiaryFixedVariant\">@color/md_theme_onTertiaryFixedVariant_mediumContrast</item>\n        <item name=\"colorSurfaceDim\">@color/md_theme_surfaceDim_mediumContrast</item>\n        <item name=\"colorSurfaceBright\">@color/md_theme_surfaceBright_mediumContrast</item>\n        <item name=\"colorSurfaceContainerLowest\">@color/md_theme_surfaceContainerLowest_mediumContrast</item>\n        <item name=\"colorSurfaceContainerLow\">@color/md_theme_surfaceContainerLow_mediumContrast</item>\n        <item name=\"colorSurfaceContainer\">@color/md_theme_surfaceContainer_mediumContrast</item>\n        <item name=\"colorSurfaceContainerHigh\">@color/md_theme_surfaceContainerHigh_mediumContrast</item>\n        <item name=\"colorSurfaceContainerHighest\">@color/md_theme_surfaceContainerHighest_mediumContrast</item>\n    </style>\n    <style name=\"ThemeOverlay.AppTheme.HighContrast\" parent=\"Theme.Material3.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/md_theme_primary_highContrast</item>\n        <item name=\"colorOnPrimary\">@color/md_theme_onPrimary_highContrast</item>\n        <item name=\"colorPrimaryContainer\">@color/md_theme_primaryContainer_highContrast</item>\n        <item name=\"colorOnPrimaryContainer\">@color/md_theme_onPrimaryContainer_highContrast</item>\n        <item name=\"colorSecondary\">@color/md_theme_secondary_highContrast</item>\n        <item name=\"colorOnSecondary\">@color/md_theme_onSecondary_highContrast</item>\n        <item name=\"colorSecondaryContainer\">@color/md_theme_secondaryContainer_highContrast</item>\n        <item name=\"colorOnSecondaryContainer\">@color/md_theme_onSecondaryContainer_highContrast</item>\n        <item name=\"colorTertiary\">@color/md_theme_tertiary_highContrast</item>\n        <item name=\"colorOnTertiary\">@color/md_theme_onTertiary_highContrast</item>\n        <item name=\"colorTertiaryContainer\">@color/md_theme_tertiaryContainer_highContrast</item>\n        <item name=\"colorOnTertiaryContainer\">@color/md_theme_onTertiaryContainer_highContrast</item>\n        <item name=\"colorError\">@color/md_theme_error_highContrast</item>\n        <item name=\"colorOnError\">@color/md_theme_onError_highContrast</item>\n        <item name=\"colorErrorContainer\">@color/md_theme_errorContainer_highContrast</item>\n        <item name=\"colorOnErrorContainer\">@color/md_theme_onErrorContainer_highContrast</item>\n        <item name=\"android:colorBackground\">@color/md_theme_background_highContrast</item>\n        <item name=\"colorOnBackground\">@color/md_theme_onBackground_highContrast</item>\n        <item name=\"colorSurface\">@color/md_theme_surface_highContrast</item>\n        <item name=\"colorOnSurface\">@color/md_theme_onSurface_highContrast</item>\n        <item name=\"colorSurfaceVariant\">@color/md_theme_surfaceVariant_highContrast</item>\n        <item name=\"colorOnSurfaceVariant\">@color/md_theme_onSurfaceVariant_highContrast</item>\n        <item name=\"colorOutline\">@color/md_theme_outline_highContrast</item>\n        <item name=\"colorOutlineVariant\">@color/md_theme_outlineVariant_highContrast</item>\n        <item name=\"colorSurfaceInverse\">@color/md_theme_inverseSurface_highContrast</item>\n        <item name=\"colorOnSurfaceInverse\">@color/md_theme_inverseOnSurface_highContrast</item>\n        <item name=\"colorPrimaryInverse\">@color/md_theme_inversePrimary_highContrast</item>\n        <item name=\"colorPrimaryFixed\">@color/md_theme_primaryFixed_highContrast</item>\n        <item name=\"colorOnPrimaryFixed\">@color/md_theme_onPrimaryFixed_highContrast</item>\n        <item name=\"colorPrimaryFixedDim\">@color/md_theme_primaryFixedDim_highContrast</item>\n        <item name=\"colorOnPrimaryFixedVariant\">@color/md_theme_onPrimaryFixedVariant_highContrast</item>\n        <item name=\"colorSecondaryFixed\">@color/md_theme_secondaryFixed_highContrast</item>\n        <item name=\"colorOnSecondaryFixed\">@color/md_theme_onSecondaryFixed_highContrast</item>\n        <item name=\"colorSecondaryFixedDim\">@color/md_theme_secondaryFixedDim_highContrast</item>\n        <item name=\"colorOnSecondaryFixedVariant\">@color/md_theme_onSecondaryFixedVariant_highContrast</item>\n        <item name=\"colorTertiaryFixed\">@color/md_theme_tertiaryFixed_highContrast</item>\n        <item name=\"colorOnTertiaryFixed\">@color/md_theme_onTertiaryFixed_highContrast</item>\n        <item name=\"colorTertiaryFixedDim\">@color/md_theme_tertiaryFixedDim_highContrast</item>\n        <item name=\"colorOnTertiaryFixedVariant\">@color/md_theme_onTertiaryFixedVariant_highContrast</item>\n        <item name=\"colorSurfaceDim\">@color/md_theme_surfaceDim_highContrast</item>\n        <item name=\"colorSurfaceBright\">@color/md_theme_surfaceBright_highContrast</item>\n        <item name=\"colorSurfaceContainerLowest\">@color/md_theme_surfaceContainerLowest_highContrast</item>\n        <item name=\"colorSurfaceContainerLow\">@color/md_theme_surfaceContainerLow_highContrast</item>\n        <item name=\"colorSurfaceContainer\">@color/md_theme_surfaceContainer_highContrast</item>\n        <item name=\"colorSurfaceContainerHigh\">@color/md_theme_surfaceContainerHigh_highContrast</item>\n        <item name=\"colorSurfaceContainerHighest\">@color/md_theme_surfaceContainerHighest_highContrast</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n\n    <style name=\"AppTheme\" parent=\"Theme.Material3.Light.NoActionBar\">\n        <item name=\"colorPrimary\">@color/md_theme_primary</item>\n        <item name=\"colorOnPrimary\">@color/md_theme_onPrimary</item>\n        <item name=\"colorPrimaryContainer\">@color/md_theme_primaryContainer</item>\n        <item name=\"colorOnPrimaryContainer\">@color/md_theme_onPrimaryContainer</item>\n        <item name=\"colorSecondary\">@color/md_theme_secondary</item>\n        <item name=\"colorOnSecondary\">@color/md_theme_onSecondary</item>\n        <item name=\"colorSecondaryContainer\">@color/md_theme_secondaryContainer</item>\n        <item name=\"colorOnSecondaryContainer\">@color/md_theme_onSecondaryContainer</item>\n        <item name=\"colorTertiary\">@color/md_theme_tertiary</item>\n        <item name=\"colorOnTertiary\">@color/md_theme_onTertiary</item>\n        <item name=\"colorTertiaryContainer\">@color/md_theme_tertiaryContainer</item>\n        <item name=\"colorOnTertiaryContainer\">@color/md_theme_onTertiaryContainer</item>\n        <item name=\"colorError\">@color/md_theme_error</item>\n        <item name=\"colorOnError\">@color/md_theme_onError</item>\n        <item name=\"colorErrorContainer\">@color/md_theme_errorContainer</item>\n        <item name=\"colorOnErrorContainer\">@color/md_theme_onErrorContainer</item>\n        <item name=\"android:colorBackground\">@color/md_theme_background</item>\n        <item name=\"colorOnBackground\">@color/md_theme_onBackground</item>\n        <item name=\"colorSurface\">@color/md_theme_surface</item>\n        <item name=\"colorOnSurface\">@color/md_theme_onSurface</item>\n        <item name=\"colorSurfaceVariant\">@color/md_theme_surfaceVariant</item>\n        <item name=\"colorOnSurfaceVariant\">@color/md_theme_onSurfaceVariant</item>\n        <item name=\"colorOutline\">@color/md_theme_outline</item>\n        <item name=\"colorOutlineVariant\">@color/md_theme_outlineVariant</item>\n        <item name=\"colorSurfaceInverse\">@color/md_theme_inverseSurface</item>\n        <item name=\"colorOnSurfaceInverse\">@color/md_theme_inverseOnSurface</item>\n        <item name=\"colorPrimaryInverse\">@color/md_theme_inversePrimary</item>\n        <item name=\"colorPrimaryFixed\">@color/md_theme_primaryFixed</item>\n        <item name=\"colorOnPrimaryFixed\">@color/md_theme_onPrimaryFixed</item>\n        <item name=\"colorPrimaryFixedDim\">@color/md_theme_primaryFixedDim</item>\n        <item name=\"colorOnPrimaryFixedVariant\">@color/md_theme_onPrimaryFixedVariant</item>\n        <item name=\"colorSecondaryFixed\">@color/md_theme_secondaryFixed</item>\n        <item name=\"colorOnSecondaryFixed\">@color/md_theme_onSecondaryFixed</item>\n        <item name=\"colorSecondaryFixedDim\">@color/md_theme_secondaryFixedDim</item>\n        <item name=\"colorOnSecondaryFixedVariant\">@color/md_theme_onSecondaryFixedVariant</item>\n        <item name=\"colorTertiaryFixed\">@color/md_theme_tertiaryFixed</item>\n        <item name=\"colorOnTertiaryFixed\">@color/md_theme_onTertiaryFixed</item>\n        <item name=\"colorTertiaryFixedDim\">@color/md_theme_tertiaryFixedDim</item>\n        <item name=\"colorOnTertiaryFixedVariant\">@color/md_theme_onTertiaryFixedVariant</item>\n        <item name=\"colorSurfaceDim\">@color/md_theme_surfaceDim</item>\n        <item name=\"colorSurfaceBright\">@color/md_theme_surfaceBright</item>\n        <item name=\"colorSurfaceContainerLowest\">@color/md_theme_surfaceContainerLowest</item>\n        <item name=\"colorSurfaceContainerLow\">@color/md_theme_surfaceContainerLow</item>\n        <item name=\"colorSurfaceContainer\">@color/md_theme_surfaceContainer</item>\n        <item name=\"colorSurfaceContainerHigh\">@color/md_theme_surfaceContainerHigh</item>\n        <item name=\"colorSurfaceContainerHighest\">@color/md_theme_surfaceContainerHighest</item>\n    </style>\n\n    <style name=\"Theme.CopyMangaNew\" parent=\"AppTheme\">\n        <item name=\"android:statusBarColor\">@android:color/transparent</item>\n        <item name=\"android:navigationBarColor\">@android:color/transparent</item>\n        <item name=\"android:enforceNavigationBarContrast\" tools:targetApi=\"q\">false</item>\n        <item name=\"android:enforceStatusBarContrast\" tools:targetApi=\"Q\">false</item>\n        <item name=\"android:navigationBarDividerColor\" tools:targetApi=\"o_mr1\">@null</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-night/colors.xml",
    "content": "<resources>\n    <color name=\"md_theme_primary\">#A5C8FF</color>\n    <color name=\"md_theme_onPrimary\">#00315E</color>\n    <color name=\"md_theme_primaryContainer\">#224876</color>\n    <color name=\"md_theme_onPrimaryContainer\">#D4E3FF</color>\n    <color name=\"md_theme_secondary\">#BCC7DC</color>\n    <color name=\"md_theme_onSecondary\">#263141</color>\n    <color name=\"md_theme_secondaryContainer\">#3D4758</color>\n    <color name=\"md_theme_onSecondaryContainer\">#D8E3F8</color>\n    <color name=\"md_theme_tertiary\">#DABDE2</color>\n    <color name=\"md_theme_onTertiary\">#3D2946</color>\n    <color name=\"md_theme_tertiaryContainer\">#553F5D</color>\n    <color name=\"md_theme_onTertiaryContainer\">#F7D8FF</color>\n    <color name=\"md_theme_error\">#FFB4AB</color>\n    <color name=\"md_theme_onError\">#690005</color>\n    <color name=\"md_theme_errorContainer\">#93000A</color>\n    <color name=\"md_theme_onErrorContainer\">#FFDAD6</color>\n    <color name=\"md_theme_background\">#111318</color>\n    <color name=\"md_theme_onBackground\">#E1E2E9</color>\n    <color name=\"md_theme_surface\">#111318</color>\n    <color name=\"md_theme_onSurface\">#E1E2E9</color>\n    <color name=\"md_theme_surfaceVariant\">#43474E</color>\n    <color name=\"md_theme_onSurfaceVariant\">#C3C6CF</color>\n    <color name=\"md_theme_outline\">#8D9199</color>\n    <color name=\"md_theme_outlineVariant\">#43474E</color>\n    <color name=\"md_theme_scrim\">#000000</color>\n    <color name=\"md_theme_inverseSurface\">#E1E2E9</color>\n    <color name=\"md_theme_inverseOnSurface\">#2E3035</color>\n    <color name=\"md_theme_inversePrimary\">#3C6090</color>\n    <color name=\"md_theme_primaryFixed\">#D4E3FF</color>\n    <color name=\"md_theme_onPrimaryFixed\">#001C3A</color>\n    <color name=\"md_theme_primaryFixedDim\">#A5C8FF</color>\n    <color name=\"md_theme_onPrimaryFixedVariant\">#224876</color>\n    <color name=\"md_theme_secondaryFixed\">#D8E3F8</color>\n    <color name=\"md_theme_onSecondaryFixed\">#111C2B</color>\n    <color name=\"md_theme_secondaryFixedDim\">#BCC7DC</color>\n    <color name=\"md_theme_onSecondaryFixedVariant\">#3D4758</color>\n    <color name=\"md_theme_tertiaryFixed\">#F7D8FF</color>\n    <color name=\"md_theme_onTertiaryFixed\">#271430</color>\n    <color name=\"md_theme_tertiaryFixedDim\">#DABDE2</color>\n    <color name=\"md_theme_onTertiaryFixedVariant\">#553F5D</color>\n    <color name=\"md_theme_surfaceDim\">#111318</color>\n    <color name=\"md_theme_surfaceBright\">#37393E</color>\n    <color name=\"md_theme_surfaceContainerLowest\">#0C0E13</color>\n    <color name=\"md_theme_surfaceContainerLow\">#191C20</color>\n    <color name=\"md_theme_surfaceContainer\">#1D2024</color>\n    <color name=\"md_theme_surfaceContainerHigh\">#282A2F</color>\n    <color name=\"md_theme_surfaceContainerHighest\">#32353A</color>\n    <color name=\"md_theme_primary_mediumContrast\">#ACCCFF</color>\n    <color name=\"md_theme_onPrimary_mediumContrast\">#001631</color>\n    <color name=\"md_theme_primaryContainer_mediumContrast\">#7092C5</color>\n    <color name=\"md_theme_onPrimaryContainer_mediumContrast\">#000000</color>\n    <color name=\"md_theme_secondary_mediumContrast\">#C1CBE0</color>\n    <color name=\"md_theme_onSecondary_mediumContrast\">#0C1726</color>\n    <color name=\"md_theme_secondaryContainer_mediumContrast\">#8791A4</color>\n    <color name=\"md_theme_onSecondaryContainer_mediumContrast\">#000000</color>\n    <color name=\"md_theme_tertiary_mediumContrast\">#DEC1E7</color>\n    <color name=\"md_theme_onTertiary_mediumContrast\">#210E2A</color>\n    <color name=\"md_theme_tertiaryContainer_mediumContrast\">#A288AB</color>\n    <color name=\"md_theme_onTertiaryContainer_mediumContrast\">#000000</color>\n    <color name=\"md_theme_error_mediumContrast\">#FFBAB1</color>\n    <color name=\"md_theme_onError_mediumContrast\">#370001</color>\n    <color name=\"md_theme_errorContainer_mediumContrast\">#FF5449</color>\n    <color name=\"md_theme_onErrorContainer_mediumContrast\">#000000</color>\n    <color name=\"md_theme_background_mediumContrast\">#111318</color>\n    <color name=\"md_theme_onBackground_mediumContrast\">#E1E2E9</color>\n    <color name=\"md_theme_surface_mediumContrast\">#111318</color>\n    <color name=\"md_theme_onSurface_mediumContrast\">#FBFAFF</color>\n    <color name=\"md_theme_surfaceVariant_mediumContrast\">#43474E</color>\n    <color name=\"md_theme_onSurfaceVariant_mediumContrast\">#C8CAD4</color>\n    <color name=\"md_theme_outline_mediumContrast\">#A0A3AB</color>\n    <color name=\"md_theme_outlineVariant_mediumContrast\">#80838B</color>\n    <color name=\"md_theme_scrim_mediumContrast\">#000000</color>\n    <color name=\"md_theme_inverseSurface_mediumContrast\">#E1E2E9</color>\n    <color name=\"md_theme_inverseOnSurface_mediumContrast\">#282A2F</color>\n    <color name=\"md_theme_inversePrimary_mediumContrast\">#234977</color>\n    <color name=\"md_theme_primaryFixed_mediumContrast\">#D4E3FF</color>\n    <color name=\"md_theme_onPrimaryFixed_mediumContrast\">#001128</color>\n    <color name=\"md_theme_primaryFixedDim_mediumContrast\">#A5C8FF</color>\n    <color name=\"md_theme_onPrimaryFixedVariant_mediumContrast\">#0A3764</color>\n    <color name=\"md_theme_secondaryFixed_mediumContrast\">#D8E3F8</color>\n    <color name=\"md_theme_onSecondaryFixed_mediumContrast\">#071120</color>\n    <color name=\"md_theme_secondaryFixedDim_mediumContrast\">#BCC7DC</color>\n    <color name=\"md_theme_onSecondaryFixedVariant_mediumContrast\">#2C3747</color>\n    <color name=\"md_theme_tertiaryFixed_mediumContrast\">#F7D8FF</color>\n    <color name=\"md_theme_onTertiaryFixed_mediumContrast\">#1C0925</color>\n    <color name=\"md_theme_tertiaryFixedDim_mediumContrast\">#DABDE2</color>\n    <color name=\"md_theme_onTertiaryFixedVariant_mediumContrast\">#432E4C</color>\n    <color name=\"md_theme_surfaceDim_mediumContrast\">#111318</color>\n    <color name=\"md_theme_surfaceBright_mediumContrast\">#37393E</color>\n    <color name=\"md_theme_surfaceContainerLowest_mediumContrast\">#0C0E13</color>\n    <color name=\"md_theme_surfaceContainerLow_mediumContrast\">#191C20</color>\n    <color name=\"md_theme_surfaceContainer_mediumContrast\">#1D2024</color>\n    <color name=\"md_theme_surfaceContainerHigh_mediumContrast\">#282A2F</color>\n    <color name=\"md_theme_surfaceContainerHighest_mediumContrast\">#32353A</color>\n    <color name=\"md_theme_primary_highContrast\">#FBFAFF</color>\n    <color name=\"md_theme_onPrimary_highContrast\">#000000</color>\n    <color name=\"md_theme_primaryContainer_highContrast\">#ACCCFF</color>\n    <color name=\"md_theme_onPrimaryContainer_highContrast\">#000000</color>\n    <color name=\"md_theme_secondary_highContrast\">#FBFAFF</color>\n    <color name=\"md_theme_onSecondary_highContrast\">#000000</color>\n    <color name=\"md_theme_secondaryContainer_highContrast\">#C1CBE0</color>\n    <color name=\"md_theme_onSecondaryContainer_highContrast\">#000000</color>\n    <color name=\"md_theme_tertiary_highContrast\">#FFF9FB</color>\n    <color name=\"md_theme_onTertiary_highContrast\">#000000</color>\n    <color name=\"md_theme_tertiaryContainer_highContrast\">#DEC1E7</color>\n    <color name=\"md_theme_onTertiaryContainer_highContrast\">#000000</color>\n    <color name=\"md_theme_error_highContrast\">#FFF9F9</color>\n    <color name=\"md_theme_onError_highContrast\">#000000</color>\n    <color name=\"md_theme_errorContainer_highContrast\">#FFBAB1</color>\n    <color name=\"md_theme_onErrorContainer_highContrast\">#000000</color>\n    <color name=\"md_theme_background_highContrast\">#111318</color>\n    <color name=\"md_theme_onBackground_highContrast\">#E1E2E9</color>\n    <color name=\"md_theme_surface_highContrast\">#111318</color>\n    <color name=\"md_theme_onSurface_highContrast\">#FFFFFF</color>\n    <color name=\"md_theme_surfaceVariant_highContrast\">#43474E</color>\n    <color name=\"md_theme_onSurfaceVariant_highContrast\">#FBFAFF</color>\n    <color name=\"md_theme_outline_highContrast\">#C8CAD4</color>\n    <color name=\"md_theme_outlineVariant_highContrast\">#C8CAD4</color>\n    <color name=\"md_theme_scrim_highContrast\">#000000</color>\n    <color name=\"md_theme_inverseSurface_highContrast\">#E1E2E9</color>\n    <color name=\"md_theme_inverseOnSurface_highContrast\">#000000</color>\n    <color name=\"md_theme_inversePrimary_highContrast\">#002A53</color>\n    <color name=\"md_theme_primaryFixed_highContrast\">#DBE7FF</color>\n    <color name=\"md_theme_onPrimaryFixed_highContrast\">#000000</color>\n    <color name=\"md_theme_primaryFixedDim_highContrast\">#ACCCFF</color>\n    <color name=\"md_theme_onPrimaryFixedVariant_highContrast\">#001631</color>\n    <color name=\"md_theme_secondaryFixed_highContrast\">#DDE7FD</color>\n    <color name=\"md_theme_onSecondaryFixed_highContrast\">#000000</color>\n    <color name=\"md_theme_secondaryFixedDim_highContrast\">#C1CBE0</color>\n    <color name=\"md_theme_onSecondaryFixedVariant_highContrast\">#0C1726</color>\n    <color name=\"md_theme_tertiaryFixed_highContrast\">#F9DEFF</color>\n    <color name=\"md_theme_onTertiaryFixed_highContrast\">#000000</color>\n    <color name=\"md_theme_tertiaryFixedDim_highContrast\">#DEC1E7</color>\n    <color name=\"md_theme_onTertiaryFixedVariant_highContrast\">#210E2A</color>\n    <color name=\"md_theme_surfaceDim_highContrast\">#111318</color>\n    <color name=\"md_theme_surfaceBright_highContrast\">#37393E</color>\n    <color name=\"md_theme_surfaceContainerLowest_highContrast\">#0C0E13</color>\n    <color name=\"md_theme_surfaceContainerLow_highContrast\">#191C20</color>\n    <color name=\"md_theme_surfaceContainer_highContrast\">#1D2024</color>\n    <color name=\"md_theme_surfaceContainerHigh_highContrast\">#282A2F</color>\n    <color name=\"md_theme_surfaceContainerHighest_highContrast\">#32353A</color>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-night/theme_overlays.xml",
    "content": "<resources>\n    <style name=\"ThemeOverlay.AppTheme.MediumContrast\" parent=\"Theme.Material3.Dark.NoActionBar\">\n        <item name=\"colorPrimary\">@color/md_theme_primary_mediumContrast</item>\n        <item name=\"colorOnPrimary\">@color/md_theme_onPrimary_mediumContrast</item>\n        <item name=\"colorPrimaryContainer\">@color/md_theme_primaryContainer_mediumContrast</item>\n        <item name=\"colorOnPrimaryContainer\">@color/md_theme_onPrimaryContainer_mediumContrast</item>\n        <item name=\"colorSecondary\">@color/md_theme_secondary_mediumContrast</item>\n        <item name=\"colorOnSecondary\">@color/md_theme_onSecondary_mediumContrast</item>\n        <item name=\"colorSecondaryContainer\">@color/md_theme_secondaryContainer_mediumContrast</item>\n        <item name=\"colorOnSecondaryContainer\">@color/md_theme_onSecondaryContainer_mediumContrast</item>\n        <item name=\"colorTertiary\">@color/md_theme_tertiary_mediumContrast</item>\n        <item name=\"colorOnTertiary\">@color/md_theme_onTertiary_mediumContrast</item>\n        <item name=\"colorTertiaryContainer\">@color/md_theme_tertiaryContainer_mediumContrast</item>\n        <item name=\"colorOnTertiaryContainer\">@color/md_theme_onTertiaryContainer_mediumContrast</item>\n        <item name=\"colorError\">@color/md_theme_error_mediumContrast</item>\n        <item name=\"colorOnError\">@color/md_theme_onError_mediumContrast</item>\n        <item name=\"colorErrorContainer\">@color/md_theme_errorContainer_mediumContrast</item>\n        <item name=\"colorOnErrorContainer\">@color/md_theme_onErrorContainer_mediumContrast</item>\n        <item name=\"android:colorBackground\">@color/md_theme_background_mediumContrast</item>\n        <item name=\"colorOnBackground\">@color/md_theme_onBackground_mediumContrast</item>\n        <item name=\"colorSurface\">@color/md_theme_surface_mediumContrast</item>\n        <item name=\"colorOnSurface\">@color/md_theme_onSurface_mediumContrast</item>\n        <item name=\"colorSurfaceVariant\">@color/md_theme_surfaceVariant_mediumContrast</item>\n        <item name=\"colorOnSurfaceVariant\">@color/md_theme_onSurfaceVariant_mediumContrast</item>\n        <item name=\"colorOutline\">@color/md_theme_outline_mediumContrast</item>\n        <item name=\"colorOutlineVariant\">@color/md_theme_outlineVariant_mediumContrast</item>\n        <item name=\"colorSurfaceInverse\">@color/md_theme_inverseSurface_mediumContrast</item>\n        <item name=\"colorOnSurfaceInverse\">@color/md_theme_inverseOnSurface_mediumContrast</item>\n        <item name=\"colorPrimaryInverse\">@color/md_theme_inversePrimary_mediumContrast</item>\n        <item name=\"colorPrimaryFixed\">@color/md_theme_primaryFixed_mediumContrast</item>\n        <item name=\"colorOnPrimaryFixed\">@color/md_theme_onPrimaryFixed_mediumContrast</item>\n        <item name=\"colorPrimaryFixedDim\">@color/md_theme_primaryFixedDim_mediumContrast</item>\n        <item name=\"colorOnPrimaryFixedVariant\">@color/md_theme_onPrimaryFixedVariant_mediumContrast</item>\n        <item name=\"colorSecondaryFixed\">@color/md_theme_secondaryFixed_mediumContrast</item>\n        <item name=\"colorOnSecondaryFixed\">@color/md_theme_onSecondaryFixed_mediumContrast</item>\n        <item name=\"colorSecondaryFixedDim\">@color/md_theme_secondaryFixedDim_mediumContrast</item>\n        <item name=\"colorOnSecondaryFixedVariant\">@color/md_theme_onSecondaryFixedVariant_mediumContrast</item>\n        <item name=\"colorTertiaryFixed\">@color/md_theme_tertiaryFixed_mediumContrast</item>\n        <item name=\"colorOnTertiaryFixed\">@color/md_theme_onTertiaryFixed_mediumContrast</item>\n        <item name=\"colorTertiaryFixedDim\">@color/md_theme_tertiaryFixedDim_mediumContrast</item>\n        <item name=\"colorOnTertiaryFixedVariant\">@color/md_theme_onTertiaryFixedVariant_mediumContrast</item>\n        <item name=\"colorSurfaceDim\">@color/md_theme_surfaceDim_mediumContrast</item>\n        <item name=\"colorSurfaceBright\">@color/md_theme_surfaceBright_mediumContrast</item>\n        <item name=\"colorSurfaceContainerLowest\">@color/md_theme_surfaceContainerLowest_mediumContrast</item>\n        <item name=\"colorSurfaceContainerLow\">@color/md_theme_surfaceContainerLow_mediumContrast</item>\n        <item name=\"colorSurfaceContainer\">@color/md_theme_surfaceContainer_mediumContrast</item>\n        <item name=\"colorSurfaceContainerHigh\">@color/md_theme_surfaceContainerHigh_mediumContrast</item>\n        <item name=\"colorSurfaceContainerHighest\">@color/md_theme_surfaceContainerHighest_mediumContrast</item>\n    </style>\n    <style name=\"ThemeOverlay.AppTheme.HighContrast\" parent=\"Theme.Material3.Dark.NoActionBar\">\n        <item name=\"colorPrimary\">@color/md_theme_primary_highContrast</item>\n        <item name=\"colorOnPrimary\">@color/md_theme_onPrimary_highContrast</item>\n        <item name=\"colorPrimaryContainer\">@color/md_theme_primaryContainer_highContrast</item>\n        <item name=\"colorOnPrimaryContainer\">@color/md_theme_onPrimaryContainer_highContrast</item>\n        <item name=\"colorSecondary\">@color/md_theme_secondary_highContrast</item>\n        <item name=\"colorOnSecondary\">@color/md_theme_onSecondary_highContrast</item>\n        <item name=\"colorSecondaryContainer\">@color/md_theme_secondaryContainer_highContrast</item>\n        <item name=\"colorOnSecondaryContainer\">@color/md_theme_onSecondaryContainer_highContrast</item>\n        <item name=\"colorTertiary\">@color/md_theme_tertiary_highContrast</item>\n        <item name=\"colorOnTertiary\">@color/md_theme_onTertiary_highContrast</item>\n        <item name=\"colorTertiaryContainer\">@color/md_theme_tertiaryContainer_highContrast</item>\n        <item name=\"colorOnTertiaryContainer\">@color/md_theme_onTertiaryContainer_highContrast</item>\n        <item name=\"colorError\">@color/md_theme_error_highContrast</item>\n        <item name=\"colorOnError\">@color/md_theme_onError_highContrast</item>\n        <item name=\"colorErrorContainer\">@color/md_theme_errorContainer_highContrast</item>\n        <item name=\"colorOnErrorContainer\">@color/md_theme_onErrorContainer_highContrast</item>\n        <item name=\"android:colorBackground\">@color/md_theme_background_highContrast</item>\n        <item name=\"colorOnBackground\">@color/md_theme_onBackground_highContrast</item>\n        <item name=\"colorSurface\">@color/md_theme_surface_highContrast</item>\n        <item name=\"colorOnSurface\">@color/md_theme_onSurface_highContrast</item>\n        <item name=\"colorSurfaceVariant\">@color/md_theme_surfaceVariant_highContrast</item>\n        <item name=\"colorOnSurfaceVariant\">@color/md_theme_onSurfaceVariant_highContrast</item>\n        <item name=\"colorOutline\">@color/md_theme_outline_highContrast</item>\n        <item name=\"colorOutlineVariant\">@color/md_theme_outlineVariant_highContrast</item>\n        <item name=\"colorSurfaceInverse\">@color/md_theme_inverseSurface_highContrast</item>\n        <item name=\"colorOnSurfaceInverse\">@color/md_theme_inverseOnSurface_highContrast</item>\n        <item name=\"colorPrimaryInverse\">@color/md_theme_inversePrimary_highContrast</item>\n        <item name=\"colorPrimaryFixed\">@color/md_theme_primaryFixed_highContrast</item>\n        <item name=\"colorOnPrimaryFixed\">@color/md_theme_onPrimaryFixed_highContrast</item>\n        <item name=\"colorPrimaryFixedDim\">@color/md_theme_primaryFixedDim_highContrast</item>\n        <item name=\"colorOnPrimaryFixedVariant\">@color/md_theme_onPrimaryFixedVariant_highContrast</item>\n        <item name=\"colorSecondaryFixed\">@color/md_theme_secondaryFixed_highContrast</item>\n        <item name=\"colorOnSecondaryFixed\">@color/md_theme_onSecondaryFixed_highContrast</item>\n        <item name=\"colorSecondaryFixedDim\">@color/md_theme_secondaryFixedDim_highContrast</item>\n        <item name=\"colorOnSecondaryFixedVariant\">@color/md_theme_onSecondaryFixedVariant_highContrast</item>\n        <item name=\"colorTertiaryFixed\">@color/md_theme_tertiaryFixed_highContrast</item>\n        <item name=\"colorOnTertiaryFixed\">@color/md_theme_onTertiaryFixed_highContrast</item>\n        <item name=\"colorTertiaryFixedDim\">@color/md_theme_tertiaryFixedDim_highContrast</item>\n        <item name=\"colorOnTertiaryFixedVariant\">@color/md_theme_onTertiaryFixedVariant_highContrast</item>\n        <item name=\"colorSurfaceDim\">@color/md_theme_surfaceDim_highContrast</item>\n        <item name=\"colorSurfaceBright\">@color/md_theme_surfaceBright_highContrast</item>\n        <item name=\"colorSurfaceContainerLowest\">@color/md_theme_surfaceContainerLowest_highContrast</item>\n        <item name=\"colorSurfaceContainerLow\">@color/md_theme_surfaceContainerLow_highContrast</item>\n        <item name=\"colorSurfaceContainer\">@color/md_theme_surfaceContainer_highContrast</item>\n        <item name=\"colorSurfaceContainerHigh\">@color/md_theme_surfaceContainerHigh_highContrast</item>\n        <item name=\"colorSurfaceContainerHighest\">@color/md_theme_surfaceContainerHighest_highContrast</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-night/themes.xml",
    "content": "<resources>\n    <style name=\"AppTheme\" parent=\"Theme.Material3.Dark.NoActionBar\">\n        <item name=\"colorPrimary\">@color/md_theme_primary</item>\n        <item name=\"colorOnPrimary\">@color/md_theme_onPrimary</item>\n        <item name=\"colorPrimaryContainer\">@color/md_theme_primaryContainer</item>\n        <item name=\"colorOnPrimaryContainer\">@color/md_theme_onPrimaryContainer</item>\n        <item name=\"colorSecondary\">@color/md_theme_secondary</item>\n        <item name=\"colorOnSecondary\">@color/md_theme_onSecondary</item>\n        <item name=\"colorSecondaryContainer\">@color/md_theme_secondaryContainer</item>\n        <item name=\"colorOnSecondaryContainer\">@color/md_theme_onSecondaryContainer</item>\n        <item name=\"colorTertiary\">@color/md_theme_tertiary</item>\n        <item name=\"colorOnTertiary\">@color/md_theme_onTertiary</item>\n        <item name=\"colorTertiaryContainer\">@color/md_theme_tertiaryContainer</item>\n        <item name=\"colorOnTertiaryContainer\">@color/md_theme_onTertiaryContainer</item>\n        <item name=\"colorError\">@color/md_theme_error</item>\n        <item name=\"colorOnError\">@color/md_theme_onError</item>\n        <item name=\"colorErrorContainer\">@color/md_theme_errorContainer</item>\n        <item name=\"colorOnErrorContainer\">@color/md_theme_onErrorContainer</item>\n        <item name=\"android:colorBackground\">@color/md_theme_background</item>\n        <item name=\"colorOnBackground\">@color/md_theme_onBackground</item>\n        <item name=\"colorSurface\">@color/md_theme_surface</item>\n        <item name=\"colorOnSurface\">@color/md_theme_onSurface</item>\n        <item name=\"colorSurfaceVariant\">@color/md_theme_surfaceVariant</item>\n        <item name=\"colorOnSurfaceVariant\">@color/md_theme_onSurfaceVariant</item>\n        <item name=\"colorOutline\">@color/md_theme_outline</item>\n        <item name=\"colorOutlineVariant\">@color/md_theme_outlineVariant</item>\n        <item name=\"colorSurfaceInverse\">@color/md_theme_inverseSurface</item>\n        <item name=\"colorOnSurfaceInverse\">@color/md_theme_inverseOnSurface</item>\n        <item name=\"colorPrimaryInverse\">@color/md_theme_inversePrimary</item>\n        <item name=\"colorPrimaryFixed\">@color/md_theme_primaryFixed</item>\n        <item name=\"colorOnPrimaryFixed\">@color/md_theme_onPrimaryFixed</item>\n        <item name=\"colorPrimaryFixedDim\">@color/md_theme_primaryFixedDim</item>\n        <item name=\"colorOnPrimaryFixedVariant\">@color/md_theme_onPrimaryFixedVariant</item>\n        <item name=\"colorSecondaryFixed\">@color/md_theme_secondaryFixed</item>\n        <item name=\"colorOnSecondaryFixed\">@color/md_theme_onSecondaryFixed</item>\n        <item name=\"colorSecondaryFixedDim\">@color/md_theme_secondaryFixedDim</item>\n        <item name=\"colorOnSecondaryFixedVariant\">@color/md_theme_onSecondaryFixedVariant</item>\n        <item name=\"colorTertiaryFixed\">@color/md_theme_tertiaryFixed</item>\n        <item name=\"colorOnTertiaryFixed\">@color/md_theme_onTertiaryFixed</item>\n        <item name=\"colorTertiaryFixedDim\">@color/md_theme_tertiaryFixedDim</item>\n        <item name=\"colorOnTertiaryFixedVariant\">@color/md_theme_onTertiaryFixedVariant</item>\n        <item name=\"colorSurfaceDim\">@color/md_theme_surfaceDim</item>\n        <item name=\"colorSurfaceBright\">@color/md_theme_surfaceBright</item>\n        <item name=\"colorSurfaceContainerLowest\">@color/md_theme_surfaceContainerLowest</item>\n        <item name=\"colorSurfaceContainerLow\">@color/md_theme_surfaceContainerLow</item>\n        <item name=\"colorSurfaceContainer\">@color/md_theme_surfaceContainer</item>\n        <item name=\"colorSurfaceContainerHigh\">@color/md_theme_surfaceContainerHigh</item>\n        <item name=\"colorSurfaceContainerHighest\">@color/md_theme_surfaceContainerHighest</item>\n    </style>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-zh-rCN/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\">写轮眼漫画</string>\n    <string name=\"recommend\">推荐</string>\n    <string name=\"day_rank\">近24小时</string>\n    <string name=\"comic_rank\">排行榜</string>\n    <string name=\"month_rank\">近30天</string>\n    <string name=\"week_rank\">近7天</string>\n    <string name=\"all_rank\">总榜</string>\n    <string name=\"hot_manga\">热门</string>\n    <string name=\"new_manga\">最新</string>\n    <string name=\"finish_manga\">完结</string>\n    <string name=\"chapter\">共 %s 章</string>\n    <string name=\"theme\">类别</string>\n    <string name=\"order\">排序</string>\n    <string name=\"error\">有些地方发生了错误</string>\n    <string name=\"retry\">重试</string>\n    <string name=\"next_chapter\">下一章</string>\n    <string name=\"about\">关于</string>\n    <string name=\"search_text\">输入搜索内容…</string>\n    <string name=\"history\">观看历史</string>\n    <string name=\"error_non_text\">没有输入文字</string>\n    <string name=\"touch_to_retry\">点击重试</string>\n    <string name=\"explore\">所有漫画</string>\n    <string name=\"load_failure\">加载失败</string>\n    <string name=\"all_clear\">全部加载完成</string>\n    <string name=\"above_chapter\">上一章</string>\n    <string name=\"slider_bar_cd\">显示当前页数的滑动条</string>\n    <string name=\"no_history\">没有观看历史</string>\n    <string name=\"japanese_r_to_l\">从右向左</string>\n    <string name=\"korea_chinese_top_to_bottom\">条漫</string>\n    <string name=\"pref_main\">通用</string>\n    <string name=\"pref_orintation\">排向偏好</string>\n    <string name=\"perf_about\">关于此项目</string>\n    <string name=\"pref_app\">项目地址</string>\n    <string name=\"pref_app_summary\">查看该项目的地址</string>\n    <string name=\"pref_about_summary\">查看该应用信息和许可证</string>\n    <string name=\"use_forgin_region\">使用海外线路</string>\n    <string name=\"use_forgin_region_summary\">使用海外线路进行请求</string>\n    <string name=\"use_forgin_region_tip\">注意：无论使用任何线路，只有图片CDN会发生变化</string>\n    <string name=\"setting\">设置</string>\n    <string name=\"last_update\">最后更新：%s</string>\n    <string name=\"download_channel_name\">下载漫画</string>\n    <string name=\"manga_download_get_ready\">准备中</string>\n    <string name=\"system\">系统</string>\n    <string name=\"clear_cache\">清除缓存</string>\n    <string name=\"cache_used\">缓存已占用 %s 的内部存储空间</string>\n    <string name=\"clear_pager_cache\">清除阅读器所产生的缓存</string>\n    <string name=\"error_in_download\">下载出错</string>\n    <string name=\"downloading\">下载中</string>\n    <string name=\"waiting\">等待中</string>\n    <string name=\"all_done\">下载完成</string>\n    <string name=\"cancel\">任务取消</string>\n    <string name=\"items_downloaded\">%s 个项目</string>\n    <string name=\"post_before_done\">完成前处理中</string>\n    <string name=\"perpare_to_finish\">准备完成中</string>\n    <string name=\"download_manga\">下载</string>\n    <string name=\"see_the_download\">查看当前正在下载的内容</string>\n    <string name=\"manga_mode_l_t_r\">从左向右</string>\n    <string name=\"reader_mode_tip\">选择阅读模式</string>\n    <string name=\"local\">本地加载</string>\n    <string name=\"in_loading_next_chapter\">加载章节中</string>\n    <string name=\"personal\">个人</string>\n    <string name=\"quick_touch\">快速点击</string>\n    <string name=\"quick_touch_summary\">点击屏幕上下部分来翻页</string>\n    <string name=\"new_version\">有更新</string>\n    <string name=\"update\">更新</string>\n    <string name=\"website_look\">查看网页</string>\n    <string name=\"disable_update_detect\">暂停更新</string>\n    <string name=\"disable_update_summary\">有可能会错过某些重要的修复</string>\n    <string name=\"home_des\">主页</string>\n    <string name=\"select_api_header\">选择API</string>\n    <string name=\"top\">地区</string>\n    <string name=\"rank_mini\">排行榜</string>\n    <string name=\"trend_up\">热度上升</string>\n    <string name=\"default_select\">没有选择</string>\n    <string name=\"no_alias\">无别名</string>\n    <string name=\"manga_info_collapse\">收起</string>\n    <string name=\"manga_info_expand\">展开</string>\n    <string name=\"no_description\">没有内容</string>\n    <string name=\"manga_detail\">漫画详情</string>\n    <string name=\"back_to_up\">\" 转到上一层级\"</string>\n    <string name=\"chapters_list\">章节列表</string>\n    <string name=\"preparing\">准备中</string>\n    <string name=\"empty_download\">下载为空</string>\n    <string name=\"download_first_5\">下载前五章</string>\n    <string name=\"download_all\">下载所有</string>\n    <string name=\"download_last_5\">下载后五章</string>\n    <string name=\"exit_select_mode\">退出选择模式</string>\n    <string name=\"switch_api_dialog_summary\">选择一个网址主机，切换后要刷新数据才可以看到效果。一般情况下如果不能确定是官方的原因但是加载不出来可以尝试切换。</string>\n    <string name=\"swith_reader_mode_dialog_summary\">切换阅读模式。一般情况下，如果你在看漫画的时候设置过了阅读模式，那么这个选项将不会影响过设置过的漫画。</string>\n    <string name=\"close_search_dock\">关闭搜索栏</string>\n    <string name=\"input_the_word\">键入搜索内容</string>\n    <string name=\"subscribe_for_updates\">订阅漫画新章节</string>\n    <string name=\"unsubscribe_for_updates\">取消订阅更新</string>\n    <string name=\"enable\">启用</string>\n    <string name=\"not_enabled\">不启用</string>\n    <string name=\"enable_update_text\">您需要启用定时更新吗？这会在特定的时间刷新漫画，您可以手动在设置里面关闭。如果不启用您可以手动刷新。</string>\n    <string name=\"confrim_update\">定时更新？</string>\n    <string name=\"subscribe_for_updates_summary\">将会尝试在固定时间检测漫画是否更新</string>\n    <string name=\"see_all\">查看所有</string>\n    <string name=\"subscribe\">订阅</string>\n    <string name=\"copy_manga_summary\">拷贝漫画第三方应用，拥有Material You 特性</string>\n    <string name=\"open_source\">开源相关</string>\n    <string name=\"update_manga\">更新漫画</string>\n    <string name=\"completed\">完成</string>\n    <string name=\"input\">输入</string>\n    <string name=\"time_detect\">检测间隔（小时）</string>\n    <string name=\"time_detect_summary\">输入检测间隔时间，为了避免吞吐量过大导致服务器检测到第三方请求，建议时长越长越好。</string>\n    <string name=\"only_wifi\">在WiFi下</string>\n    <string name=\"only_charging\">在充电时</string>\n    <string name=\"low_power\">在低电量时</string>\n    <string name=\"update_constant\">更新条件</string>\n    <string name=\"update_constant_support_text\">设置更新时的条件</string>\n    <string name=\"work_information\">Work 信息</string>\n    <string name=\"work_info_summary\">查看该应用所使用的work的信息</string>\n    <string name=\"successed\">已成功</string>\n    <string name=\"running\">运行中</string>\n    <string name=\"enqueue\">等待中</string>\n    <string name=\"no_select_constants\">无限制</string>\n    <string name=\"read_in\">• 读到第 %d 页</string>\n    <string name=\"refresh\">手动刷新</string>\n    <string name=\"continue_read\">继续阅读</string>\n    <string name=\"start_read\">开始阅读</string>\n    <string name=\"search_is_empty\">搜索结果为空</string>\n    <string name=\"info_read_in\">读到第 %d 章 第 %d 页</string>\n    <string name=\"theme_mode\">主题模式</string>\n    <string name=\"theme_light\">日间主题</string>\n    <string name=\"theme_dark\">夜间主题</string>\n    <string name=\"theme_with_system\">跟随系统</string>\n    <string name=\"theme_mode_support_text\">选择系统主题模式，在某些本身就没有“夜间模式”的系统上“跟随系统”会变得没有意义。</string>\n    <string name=\"cut_out_display\">刘海区域是否显示内容</string>\n    <string name=\"cut_out_display_summary\">建议打开，如果关闭刘海区域将会显示为黑色</string>\n    <string name=\"no_next_chapetr\">无下一章节</string>\n    <string name=\"no_privous_chapter\">无上一章节</string>\n    <string name=\"tip_subscribe\">注意：如果您的手机对后台管理比较激进，可能不会更新。</string>\n    <string name=\"delete\">删除</string>\n    <string name=\"topic\">专题</string>\n    <string name=\"topic_detail_text\">专题详情</string>\n    <string name=\"cache_size_setting\">缓存大小</string>\n    <string name=\"cache_size_setting_supporting_text\">设置对于阅读所产生的缓存大小上限（Mb）</string>\n    <string name=\"read_finished\">• 已看完</string>\n    <string name=\"mark_to_read\">标记已读</string>\n    <string name=\"mark_to_no_read\">标记为未读</string>\n    <string name=\"no_content\">无内容</string>\n    <string name=\"login_text\">登录</string>\n    <string name=\"user_name_text\">用户名</string>\n    <string name=\"password_text\">密码</string>\n    <string name=\"no_login\">没有登录</string>\n    <string name=\"login_personal\">登录用户</string>\n    <string name=\"shelf_cloud\">云端书库</string>\n    <string name=\"local_history\">本地历史</string>\n    <string name=\"web_history\">网页历史</string>\n    <string name=\"re_login\">重新登录</string>\n    <string name=\"gender\">性别</string>\n    <string name=\"nickname_text\">昵称</string>\n    <string name=\"fatal_error\">致命错误</string>\n    <string name=\"try_to_send_to_me\">请尝试发送给作者</string>\n    <string name=\"send\">发送</string>\n    <string name=\"finish_this\">结束</string>\n    <string name=\"add\">添加</string>\n    <string name=\"personal_info\">个人信息</string>\n    <string name=\"author_choice\">选择作者</string>\n    <string name=\"author_combine\">一共 %s 位作者</string>\n    <string name=\"authors_manga\">該作者的所有漫畫</string>\n    <string name=\"web_point_enable\">使用网页端阅读点</string>\n    <string name=\"web_point_enable_summary\">从网页浏览的历史记录开始观看</string>\n    <string name=\"comment_text\">评论</string>\n    <string name=\"login_expired\">登录过期</string>\n    <string name=\"login_failure\">登录失败</string>\n    <string name=\"web_point_warning\">须知：该功能不知道是否稳定，如果此选项影响观看建议关闭。并且该功能不会精确到页数。</string>\n    <string name=\"web_point_tip\">注意：如果没有登录或是登录过期将会使用本地记录。</string>\n    <string name=\"add_to_lib\">添加到书架</string>\n    <string name=\"remove_add_to_lib\">从书架中移除</string>\n    <string name=\"type_send_content\">输入内容…</string>\n    <string name=\"send_comment_bar_title\">发送评论</string>\n    <string name=\"comic_comment_title\">漫画评论</string>\n    <string name=\"search_result\">搜索结果</string>\n    <string name=\"send_comment\">发送</string>\n    <string name=\"pause\">暂停</string>\n    <string name=\"resume\">继续</string>\n    <string name=\"only_on_wifi\">仅在Wi-Fi下下载漫画</string>\n    <string name=\"only_on_wifi_summary\">开启后，下载漫画仅会在WI-FI下下载</string>\n    <string name=\"failure_download\">下载失败</string>\n    <string name=\"prerequisites_miss\">先决条件未满足</string>\n    <string name=\"thankful_app\">灵感来源</string>\n    <string name=\"general_warning\">本开源软件不会对软件中的任何内容负责</string>\n    <string name=\"general_tips\">漫画章节、漫画的图片、漫画的其他数据经由拷贝漫画官方提供</string>\n    <string name=\"download_list\">下载队列</string>\n    <string name=\"disclaimer\">免责声明</string>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-zh-rHK/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--使用繁化姬进行转换-->\n<resources>\n    <string name=\"app_name\">寫輪眼漫畫</string>\n    <string name=\"recommend\">推薦</string>\n    <string name=\"day_rank\">近24小時</string>\n    <string name=\"comic_rank\">排行榜</string>\n    <string name=\"month_rank\">近30天</string>\n    <string name=\"week_rank\">近7天</string>\n    <string name=\"all_rank\">總榜</string>\n    <string name=\"hot_manga\">熱門</string>\n    <string name=\"new_manga\">最新</string>\n    <string name=\"finish_manga\">完結</string>\n    <string name=\"chapter\">共 %s 章</string>\n    <string name=\"theme\">類別</string>\n    <string name=\"order\">排序</string>\n    <string name=\"error\">有些地方發生了錯誤</string>\n    <string name=\"retry\">重試</string>\n    <string name=\"next_chapter\">下一章</string>\n    <string name=\"about\">關於</string>\n    <string name=\"search_text\">輸入搜索內容…</string>\n    <string name=\"history\">觀看歷史</string>\n    <string name=\"error_non_text\">沒有輸入文字</string>\n    <string name=\"touch_to_retry\">點擊重試</string>\n    <string name=\"explore\">所有漫畫</string>\n    <string name=\"load_failure\">加載失敗</string>\n    <string name=\"all_clear\">全部加載完成</string>\n    <string name=\"above_chapter\">上一章</string>\n    <string name=\"slider_bar_cd\">顯示當前頁數的滑動條</string>\n    <string name=\"no_history\">沒有觀看歷史</string>\n    <string name=\"japanese_r_to_l\">從右向左</string>\n    <string name=\"korea_chinese_top_to_bottom\">條漫</string>\n    <string name=\"pref_main\">通用</string>\n    <string name=\"pref_orintation\">排向偏好</string>\n    <string name=\"perf_about\">關於此項目</string>\n    <string name=\"pref_app\">項目地址</string>\n    <string name=\"pref_app_summary\">查看該項目的地址</string>\n    <string name=\"pref_about_summary\">查看該應用資訊和許可證</string>\n    <string name=\"use_forgin_region\">使用海外線路</string>\n    <string name=\"use_forgin_region_summary\">使用海外線路進行請求</string>\n    <string name=\"use_forgin_region_tip\">注意：無論使用任何線路，只有圖片CDN會發生變化</string>\n    <string name=\"setting\">設置</string>\n    <string name=\"last_update\">最後更新：%s</string>\n    <string name=\"download_channel_name\">下載漫畫</string>\n    <string name=\"manga_download_get_ready\">準備中</string>\n    <string name=\"system\">系統</string>\n    <string name=\"clear_cache\">清除緩存</string>\n    <string name=\"cache_used\">緩存已佔用 %s 的內部存儲空間</string>\n    <string name=\"clear_pager_cache\">清除閱讀器所產生的緩存</string>\n    <string name=\"error_in_download\">下載出錯</string>\n    <string name=\"downloading\">下載中</string>\n    <string name=\"waiting\">等待中</string>\n    <string name=\"all_done\">下載完成</string>\n    <string name=\"cancel\">任務取消</string>\n    <string name=\"items_downloaded\">%s 個項目</string>\n    <string name=\"post_before_done\">完成前處理中</string>\n    <string name=\"perpare_to_finish\">準備完成中</string>\n    <string name=\"download_manga\">下載</string>\n    <string name=\"see_the_download\">查看當前正在下載的內容</string>\n    <string name=\"manga_mode_l_t_r\">從左向右</string>\n    <string name=\"reader_mode_tip\">選擇閱讀模式</string>\n    <string name=\"local\">本地加載</string>\n    <string name=\"in_loading_next_chapter\">加載章節中</string>\n    <string name=\"personal\">個人</string>\n    <string name=\"quick_touch\">快速點擊</string>\n    <string name=\"quick_touch_summary\">點擊螢幕上下部分來翻頁</string>\n    <string name=\"new_version\">有更新</string>\n    <string name=\"update\">更新</string>\n    <string name=\"website_look\">查看網頁</string>\n    <string name=\"disable_update_detect\">暫停更新</string>\n    <string name=\"disable_update_summary\">有可能會錯過某些重要的修復</string>\n    <string name=\"home_des\">主頁</string>\n    <string name=\"select_api_header\">選擇API</string>\n    <string name=\"top\">地區</string>\n    <string name=\"rank_mini\">排行榜</string>\n    <string name=\"trend_up\">熱度上升</string>\n    <string name=\"default_select\">沒有選擇</string>\n    <string name=\"no_alias\">無別名</string>\n    <string name=\"manga_info_collapse\">收起</string>\n    <string name=\"manga_info_expand\">展開</string>\n    <string name=\"no_description\">沒有內容</string>\n    <string name=\"manga_detail\">漫畫詳情</string>\n    <string name=\"back_to_up\">\" 轉到上一層級\"</string>\n    <string name=\"chapters_list\">章節列表</string>\n    <string name=\"preparing\">準備中</string>\n    <string name=\"empty_download\">下載為空</string>\n    <string name=\"download_first_5\">下載前五章</string>\n    <string name=\"download_all\">下載所有</string>\n    <string name=\"download_last_5\">下載後五章</string>\n    <string name=\"exit_select_mode\">退出選擇模式</string>\n    <string name=\"switch_api_dialog_summary\">選擇一個網址主機，切換後要刷新數據才可以看到效果。一般情況下如果不能確定是官方的原因但是加載不出來可以嘗試切換。</string>\n    <string name=\"swith_reader_mode_dialog_summary\">切換閱讀模式。一般情況下，如果你在看漫畫的時候設置過了閱讀模式，那麼這個選項將不會影響過設置過的漫畫。</string>\n    <string name=\"close_search_dock\">關閉搜索欄</string>\n    <string name=\"input_the_word\">鍵入搜索內容</string>\n    <string name=\"subscribe_for_updates\">訂閱漫畫新章節</string>\n    <string name=\"unsubscribe_for_updates\">取消訂閱更新</string>\n    <string name=\"enable\">啟用</string>\n    <string name=\"not_enabled\">不啟用</string>\n    <string name=\"enable_update_text\">您需要啟用定時更新嗎？這會在特定的時間刷新漫畫，您可以手動在設置裏面關閉。如果不啟用您可以手動刷新。</string>\n    <string name=\"confrim_update\">定時更新？</string>\n    <string name=\"subscribe_for_updates_summary\">將會嘗試在固定時間檢測漫畫是否更新</string>\n    <string name=\"see_all\">查看所有</string>\n    <string name=\"subscribe\">訂閱</string>\n    <string name=\"copy_manga_summary\">拷貝漫畫第三方應用，擁有Material You 特性</string>\n    <string name=\"open_source\">開源相關</string>\n    <string name=\"update_manga\">更新漫畫</string>\n    <string name=\"completed\">完成</string>\n    <string name=\"input\">輸入</string>\n    <string name=\"time_detect\">檢測間隔（小時）</string>\n    <string name=\"time_detect_summary\">輸入檢測間隔時間，為了避免吞吐量過大導致伺服器檢測到第三方請求，建議時長越長越好。</string>\n    <string name=\"only_wifi\">在WiFi下</string>\n    <string name=\"only_charging\">在充電時</string>\n    <string name=\"low_power\">在低電量時</string>\n    <string name=\"update_constant\">更新條件</string>\n    <string name=\"update_constant_support_text\">設置更新時的條件</string>\n    <string name=\"work_information\">Work 資訊</string>\n    <string name=\"work_info_summary\">查看該應用所使用的work的資訊</string>\n    <string name=\"successed\">已成功</string>\n    <string name=\"running\">運行中</string>\n    <string name=\"enqueue\">等待中</string>\n    <string name=\"no_select_constants\">無限制</string>\n    <string name=\"read_in\">• 讀到第 %d 頁</string>\n    <string name=\"refresh\">手動刷新</string>\n    <string name=\"continue_read\">繼續閱讀</string>\n    <string name=\"start_read\">開始閱讀</string>\n    <string name=\"search_is_empty\">搜索結果為空</string>\n    <string name=\"info_read_in\">讀到第 %d 章 第 %d 頁</string>\n    <string name=\"theme_mode\">主題模式</string>\n    <string name=\"theme_light\">日間主題</string>\n    <string name=\"theme_dark\">夜間主題</string>\n    <string name=\"theme_with_system\">跟隨系統</string>\n    <string name=\"theme_mode_support_text\">選擇系統主題模式，在某些本身就沒有“夜間模式”的系統上“跟隨系統”會變得沒有意義。</string>\n    <string name=\"cut_out_display\">瀏海區域是否顯示內容</string>\n    <string name=\"cut_out_display_summary\">建議打開，如果關閉瀏海區域將會顯示為黑色</string>\n    <string name=\"no_next_chapetr\">無下一章節</string>\n    <string name=\"no_privous_chapter\">無上一章節</string>\n    <string name=\"tip_subscribe\">注意：如果您的手機對後台管理比較激進，可能不會更新。</string>\n    <string name=\"delete\">刪除</string>\n    <string name=\"topic\">專題</string>\n    <string name=\"topic_detail_text\">專題詳情</string>\n    <string name=\"cache_size_setting\">緩存大小</string>\n    <string name=\"cache_size_setting_supporting_text\">設置對於閱讀所產生的緩存大小上限（Mb）</string>\n    <string name=\"read_finished\">• 已看完</string>\n    <string name=\"mark_to_read\">標記已讀</string>\n    <string name=\"mark_to_no_read\">標記為未讀</string>\n    <string name=\"no_content\">無內容</string>\n    <string name=\"login_text\">登錄</string>\n    <string name=\"user_name_text\">用戶名</string>\n    <string name=\"password_text\">密碼</string>\n    <string name=\"no_login\">沒有登錄</string>\n    <string name=\"login_personal\">登錄用戶</string>\n    <string name=\"shelf_cloud\">雲端書庫</string>\n    <string name=\"local_history\">本地歷史</string>\n    <string name=\"web_history\">網頁歷史</string>\n    <string name=\"re_login\">重新登錄</string>\n    <string name=\"gender\">性別</string>\n    <string name=\"nickname_text\">暱稱</string>\n    <string name=\"fatal_error\">致命錯誤</string>\n    <string name=\"try_to_send_to_me\">請嘗試發送給作者</string>\n    <string name=\"send\">發送</string>\n    <string name=\"finish_this\">結束</string>\n    <string name=\"add\">添加</string>\n    <string name=\"personal_info\">個人資訊</string>\n    <string name=\"author_choice\">選擇作者</string>\n    <string name=\"author_combine\">一共 %s 位作者</string>\n    <string name=\"authors_manga\">該作者的所有漫畫</string>\n    <string name=\"web_point_enable\">使用網頁端閱讀點</string>\n    <string name=\"web_point_enable_summary\">从网页浏览的历史记录开始观看</string>\n    <string name=\"comment_text\">評論</string>\n    <string name=\"login_expired\">登錄過期</string>\n    <string name=\"login_failure\">登錄失敗</string>\n    <string name=\"web_point_warning\">瞭解：該功能不知道是否穩定，如果此選項影響觀看建議關閉。</string>\n    <string name=\"web_point_tip\">注意：如果沒有登錄或是登錄過期將會使用本地記錄。</string>\n    <string name=\"add_to_lib\">添加到書架</string>\n    <string name=\"remove_add_to_lib\">從書架中移除</string>\n    <string name=\"type_send_content\">输入内容…</string>\n    <string name=\"send_comment_bar_title\">發送評論</string>\n    <string name=\"comic_comment_title\">漫畫評論</string>\n    <string name=\"search_result\">搜索结果</string>\n    <string name=\"send_comment\">發送</string>\n    <string name=\"pause\">暫停</string>\n    <string name=\"resume\">恢復</string>\n    <string name=\"only_on_wifi\">僅在Wi-Fi下載漫畫</string>\n    <string name=\"only_on_wifi_summary\">開啟後，下載漫畫只會在WI-FI下載</string>\n    <string name=\"failure_download\">下載失敗</string>\n    <string name=\"prerequisites_miss\">先決條件未滿足</string>\n    <string name=\"thankful_app\">靈感來源</string>\n    <string name=\"general_warning\">本開源軟體不會對軟體中的任何內容負責</string>\n    <string name=\"general_tips\">漫畫章節、漫畫的圖片、漫畫的其他資料經由拷貝漫畫官方提供</string>\n    <string name=\"download_list\">下载队列</string>\n    <string name=\"disclaimer\">免责声明</string>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-zh-rTW/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--使用繁化姬进行转换-->\n<resources>\n    <string name=\"app_name\">寫輪眼漫畫</string>\n    <string name=\"recommend\">推薦</string>\n    <string name=\"day_rank\">近24小時</string>\n    <string name=\"comic_rank\">排行榜</string>\n    <string name=\"month_rank\">近30天</string>\n    <string name=\"week_rank\">近7天</string>\n    <string name=\"all_rank\">總榜</string>\n    <string name=\"hot_manga\">熱門</string>\n    <string name=\"new_manga\">最新</string>\n    <string name=\"finish_manga\">完結</string>\n    <string name=\"chapter\">共 %s 章</string>\n    <string name=\"theme\">類別</string>\n    <string name=\"order\">排序</string>\n    <string name=\"error\">有些地方發生了錯誤</string>\n    <string name=\"retry\">重試</string>\n    <string name=\"next_chapter\">下一章</string>\n    <string name=\"about\">關於</string>\n    <string name=\"search_text\">輸入搜索內容…</string>\n    <string name=\"history\">觀看歷史</string>\n    <string name=\"error_non_text\">沒有輸入文字</string>\n    <string name=\"touch_to_retry\">點擊重試</string>\n    <string name=\"explore\">所有漫畫</string>\n    <string name=\"load_failure\">載入失敗</string>\n    <string name=\"all_clear\">全部載入完成</string>\n    <string name=\"above_chapter\">上一章</string>\n    <string name=\"slider_bar_cd\">顯示當前頁數的滑動條</string>\n    <string name=\"no_history\">沒有觀看歷史</string>\n    <string name=\"japanese_r_to_l\">從右向左</string>\n    <string name=\"korea_chinese_top_to_bottom\">條漫</string>\n    <string name=\"pref_main\">通用</string>\n    <string name=\"pref_orintation\">排向偏好</string>\n    <string name=\"perf_about\">關於此項目</string>\n    <string name=\"pref_app\">項目地址</string>\n    <string name=\"pref_app_summary\">查看該項目的地址</string>\n    <string name=\"pref_about_summary\">查看該應用訊息和許可證</string>\n    <string name=\"use_forgin_region\">使用海外線路</string>\n    <string name=\"use_forgin_region_summary\">使用海外線路進行請求</string>\n    <string name=\"use_forgin_region_tip\">注意：無論使用任何線路，只有圖片CDN會發生變化</string>\n    <string name=\"setting\">設置</string>\n    <string name=\"last_update\">最後更新：%s</string>\n    <string name=\"download_channel_name\">下載漫畫</string>\n    <string name=\"manga_download_get_ready\">準備中</string>\n    <string name=\"system\">系統</string>\n    <string name=\"clear_cache\">清除快取</string>\n    <string name=\"cache_used\">快取已占用 %s 的內部儲存空間</string>\n    <string name=\"clear_pager_cache\">清除閱讀器所產生的快取</string>\n    <string name=\"error_in_download\">下載出錯</string>\n    <string name=\"downloading\">下載中</string>\n    <string name=\"waiting\">等待中</string>\n    <string name=\"all_done\">下載完成</string>\n    <string name=\"cancel\">任務取消</string>\n    <string name=\"items_downloaded\">%s 個項目</string>\n    <string name=\"post_before_done\">完成前處理中</string>\n    <string name=\"perpare_to_finish\">準備完成中</string>\n    <string name=\"download_manga\">下載</string>\n    <string name=\"see_the_download\">查看當前正在下載的內容</string>\n    <string name=\"manga_mode_l_t_r\">從左向右</string>\n    <string name=\"reader_mode_tip\">選擇閱讀模式</string>\n    <string name=\"local\">本地載入</string>\n    <string name=\"in_loading_next_chapter\">載入章節中</string>\n    <string name=\"personal\">個人</string>\n    <string name=\"quick_touch\">快速點擊</string>\n    <string name=\"quick_touch_summary\">點擊螢幕上下部分來翻頁</string>\n    <string name=\"new_version\">有更新</string>\n    <string name=\"update\">更新</string>\n    <string name=\"website_look\">查看網頁</string>\n    <string name=\"disable_update_detect\">暫停更新</string>\n    <string name=\"disable_update_summary\">有可能會錯過某些重要的修復</string>\n    <string name=\"home_des\">首頁</string>\n    <string name=\"select_api_header\">選擇API</string>\n    <string name=\"top\">地區</string>\n    <string name=\"rank_mini\">排行榜</string>\n    <string name=\"trend_up\">熱度上升</string>\n    <string name=\"default_select\">沒有選擇</string>\n    <string name=\"no_alias\">無別名</string>\n    <string name=\"manga_info_collapse\">收起</string>\n    <string name=\"manga_info_expand\">展開</string>\n    <string name=\"no_description\">沒有內容</string>\n    <string name=\"manga_detail\">漫畫詳情</string>\n    <string name=\"back_to_up\">\" 轉到上一層級\"</string>\n    <string name=\"chapters_list\">章節列表</string>\n    <string name=\"preparing\">準備中</string>\n    <string name=\"empty_download\">下載為空</string>\n    <string name=\"download_first_5\">下載前五章</string>\n    <string name=\"download_all\">下載所有</string>\n    <string name=\"download_last_5\">下載後五章</string>\n    <string name=\"exit_select_mode\">退出選擇模式</string>\n    <string name=\"switch_api_dialog_summary\">選擇一個網址主機，切換後要刷新數據才可以看到效果。一般情況下如果不能確定是官方的原因但是載入不出來可以嘗試切換。</string>\n    <string name=\"swith_reader_mode_dialog_summary\">切換閱讀模式。一般情況下，如果你在看漫畫的時候設置過了閱讀模式，那麼這個選項將不會影響過設置過的漫畫。</string>\n    <string name=\"close_search_dock\">關閉搜索欄</string>\n    <string name=\"input_the_word\">鍵入搜索內容</string>\n    <string name=\"subscribe_for_updates\">訂閱漫畫新章節</string>\n    <string name=\"unsubscribe_for_updates\">取消訂閱更新</string>\n    <string name=\"enable\">啟用</string>\n    <string name=\"not_enabled\">不啟用</string>\n    <string name=\"enable_update_text\">您需要啟用定時更新嗎？這會在特定的時間刷新漫畫，您可以手動在設置裡面關閉。如果不啟用您可以手動刷新。</string>\n    <string name=\"confrim_update\">定時更新？</string>\n    <string name=\"subscribe_for_updates_summary\">將會嘗試在固定時間檢測漫畫是否更新</string>\n    <string name=\"see_all\">查看所有</string>\n    <string name=\"subscribe\">訂閱</string>\n    <string name=\"copy_manga_summary\">拷貝漫畫第三方應用，擁有Material You 特性</string>\n    <string name=\"open_source\">開源相關</string>\n    <string name=\"update_manga\">更新漫畫</string>\n    <string name=\"completed\">完成</string>\n    <string name=\"input\">輸入</string>\n    <string name=\"time_detect\">檢測間隔（小時）</string>\n    <string name=\"time_detect_summary\">輸入檢測間隔時間，為了避免吞吐量過大導致伺服器檢測到第三方請求，建議時長越長越好。</string>\n    <string name=\"only_wifi\">在WiFi下</string>\n    <string name=\"only_charging\">在充電時</string>\n    <string name=\"low_power\">在低電量時</string>\n    <string name=\"update_constant\">更新條件</string>\n    <string name=\"update_constant_support_text\">設置更新時的條件</string>\n    <string name=\"work_information\">Work 訊息</string>\n    <string name=\"work_info_summary\">查看該應用所使用的work的訊息</string>\n    <string name=\"successed\">已成功</string>\n    <string name=\"running\">運行中</string>\n    <string name=\"enqueue\">等待中</string>\n    <string name=\"no_select_constants\">無限制</string>\n    <string name=\"read_in\">• 讀到 %d 頁</string>\n    <string name=\"refresh\">手動刷新</string>\n    <string name=\"continue_read\">繼續閲讀</string>\n    <string name=\"start_read\">開始閲讀</string>\n    <string name=\"search_is_empty\">搜索結果爲空</string>\n    <string name=\"info_read_in\">讀到 第 %d 章 第 %d 頁</string>\n    <string name=\"theme_mode\">主題模式</string>\n    <string name=\"theme_light\">日間主題</string>\n    <string name=\"theme_dark\">夜間模式</string>\n    <string name=\"theme_with_system\">系統跟隨</string>\n    <string name=\"theme_mode_support_text\">選擇系統主題模式，在某些本身就沒有“夜間模式”的系統上“跟隨系統”會變得沒有意義。</string>\n    <string name=\"cut_out_display\">劉海區域是否展示內容</string>\n    <string name=\"cut_out_display_summary\">建議開啓，如果關掉劉海區域將會顯示為黑色</string>\n    <string name=\"no_next_chapetr\">無下一章節</string>\n    <string name=\"no_privous_chapter\">無上一章節</string>\n    <string name=\"tip_subscribe\">注意：如果您的手機對後台管理比較激進，可能不會更新。</string>\n    <string name=\"delete\">刪除</string>\n    <string name=\"topic\">專題</string>\n    <string name=\"topic_detail_text\">專題詳情</string>\n    <string name=\"cache_size_setting\">缓存大小</string>\n    <string name=\"cache_size_setting_supporting_text\">設置對於閱讀所產生的快取大小上限（兆字節）</string>\n    <string name=\"read_finished\">• 已看完</string>\n    <string name=\"mark_to_read\">標記爲已讀</string>\n    <string name=\"mark_to_no_read\">標記爲未讀</string>\n    <string name=\"no_content\">沒有内容</string>\n    <string name=\"login_text\">登錄</string>\n    <string name=\"user_name_text\">用戶名</string>\n    <string name=\"password_text\">密碼</string>\n    <string name=\"no_login\">沒有登錄</string>\n    <string name=\"shelf_cloud\">雲端書架</string>\n    <string name=\"login_personal\">登錄用戶</string>\n    <string name=\"local_history\">本地記錄</string>\n    <string name=\"web_history\">遠端記錄</string>\n    <string name=\"re_login\">重新登入</string>\n    <string name=\"gender\">性別</string>\n    <string name=\"nickname_text\">暱稱</string>\n    <string name=\"fatal_error\">致命錯誤</string>\n    <string name=\"try_to_send_to_me\">請嘗試發送給作者</string>\n    <string name=\"send\">發送</string>\n    <string name=\"finish_this\">結束</string>\n    <string name=\"add\">添加</string>\n    <string name=\"personal_info\">個人資訊</string>\n    <string name=\"author_choice\">選擇作者</string>\n    <string name=\"author_combine\">一共 %s 位作者</string>\n    <string name=\"web_point_enable\">使用網頁端閱讀點</string>\n    <string name=\"web_point_enable_summary\">對網頁端瀏覽過的漫畫有效，啟用後如該漫畫在網頁看過，繼續觀看將不會使用本地記錄。</string>\n    <string name=\"comment_text\">討論串</string>\n    <string name=\"login_expired\">登錄過期</string>\n    <string name=\"login_failure\">登錄失敗</string>\n    <string name=\"web_point_warning\">明白：該功能不知道是否穩定，如果此選項影響觀看建議關閉。</string>\n    <string name=\"web_point_tip\">注意：如果沒有登錄或是登錄過期將會使用本地記錄。</string>\n    <string name=\"add_to_lib\">添加到書架</string>\n    <string name=\"remove_add_to_lib\">從書架中移除</string>\n    <string name=\"type_send_content\">输入内容…</string>\n    <string name=\"send_comment_bar_title\">發送評論</string>\n    <string name=\"comic_comment_title\">漫畫評論</string>\n    <string name=\"search_result\">搜索结果</string>\n    <string name=\"send_comment\">發送</string>\n    <string name=\"pause\">暫停</string>\n    <string name=\"resume\">恢復</string>\n    <string name=\"only_on_wifi\">僅在Wi-Fi下載漫畫</string>\n    <string name=\"only_on_wifi_summary\">開啟後，下載漫畫只會在WI-FI下載</string>\n    <string name=\"failure_download\">下載失敗</string>\n    <string name=\"prerequisites_miss\">先決條件未滿足</string>\n    <string name=\"thankful_app\">靈感來源</string>\n    <string name=\"general_warning\">本開源軟體不會對軟體中的任何內容負責</string>\n    <string name=\"general_tips\">漫畫章節、漫畫的圖片、漫畫的其他資料經由拷貝漫畫官方提供</string>\n    <string name=\"download_list\">下载队列</string>\n    <string name=\"disclaimer\">免责声明</string>\n</resources>"
  },
  {
    "path": "app/src/test/java/com/shicheeng/copymanga/ExampleUnitTest.java",
    "content": "package com.shicheeng.copymanga;\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.\nplugins {\n    id 'com.android.application' version '8.2.2' apply false\n    id 'com.android.library' version '8.2.2' apply false\n    id 'org.jetbrains.kotlin.android' version '1.9.22' apply false\n    id 'org.jetbrains.kotlin.plugin.parcelize' version '1.6.21' apply false\n    id \"androidx.navigation.safeargs.kotlin\" version '2.5.3' apply false\n    id 'com.mikepenz.aboutlibraries.plugin' version \"10.5.2\" apply false\n    id 'com.google.dagger.hilt.android' version '2.48' apply false\n    id 'com.google.devtools.ksp' version '1.9.22-1.0.16' apply false\n}\n\ntasks.register('clean', Delete) {\n    delete rootProject.buildDir\n}"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Mar 09 21:22:47 CST 2022\ndistributionBase=GRADLE_USER_HOME\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-8.2-bin.zip\ndistributionPath=wrapper/dists\nzipStorePath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\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=-Xmx2048m -Dfile.encoding=UTF-8\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# Enables namespacing of each library's R class so that its R class includes only the\n# resources declared in the library itself and none from the library's dependencies,\n# thereby reducing the size of the R class for that library\nandroid.nonTransitiveRClass=true\nandroid.nonFinalResIds=false"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\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='\"-Xmx64m\" \"-Xms64m\"'\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\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 or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\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=`expr $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\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto execute\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto execute\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "local.properties",
    "content": "## This file is automatically generated by Android Studio.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# This file should *NOT* be checked into Version Control Systems,\n# as it contains information specific to your local configuration.\n#\n# Location of the SDK. This is only used by Gradle.\n# For customization when using a Version Control System, please read the\n# header note.\nsdk.dir=C\\:\\\\Users\\\\ShihCheeng\\\\AppData\\\\Local\\\\Android\\\\Sdk"
  },
  {
    "path": "resources.properties",
    "content": "unqualifiedResLocale=zh-CN"
  },
  {
    "path": "settings.gradle",
    "content": "pluginManagement {\n    repositories {\n        gradlePluginPortal()\n        google()\n        mavenCentral()\n    }\n}\ndependencyResolutionManagement {\n    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)\n    repositories {\n        google()\n        mavenCentral()\n        maven { url 'https://jitpack.io' }\n    }\n}\nrootProject.name = \"CopyMangaJava\"\ninclude ':app'\n"
  }
]