31 Commits

Author SHA1 Message Date
a2489c4987 docs: 更新README文档,突出项目功能亮点
- 新增"功能亮点"部分,重点展示已完成的核心功能
  - 智能数据分析:月度/年度报表、详细分析、多维度统计
  - 预算管理系统:多层级预算、实时监控、灵活配置
  - 数据安全保障:备份加密、离线优先、隐私保护
  - 现代化设计:Material 3、深色模式、响应式布局
- 更新主要特性,标注预算管理为"基本完成"
- 更新v1.5版本历史,记录崩溃修复和功能优化
- 优化文档结构,提升可读性和专业度

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-20 00:25:07 +08:00
562617ca11 fix: 修复DetailedAnalysisReport中嵌套LazyColumn导致的崩溃
- 将DetailedAnalysisReport中的LazyColumn改为Column
- 移除所有item{}包装,直接使用普通组件布局
- 解决'Vertically scrollable component was measured with an infinity maximum height constraints'错误

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-20 00:20:59 +08:00
74cc6f36a9 feat: 优化月度/年度报表和数据分析页面
- 创建 MonthlyYearlyReport 组件,显示收支对比、盈余状况、储蓄率和日均消费
- 创建 DetailedAnalysisReport 组件,提供详细的分类统计分析
  - 支出/收入分类明细与占比
  - TOP5分类排行榜(金银铜奖牌设计)
  - 可视化进度条和百分比显示
- 在 AnalysisScreen 中新增"报表"视图模式
  - 支持分类、成员、报表三种视图切换
  - 集成月度/年度报表和详细分析报表
- 更新 README:标记月度/年度报表功能为已完成
- 更新 v1.5 版本历史,记录数据分析优化内容

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-20 00:17:49 +08:00
e651086e6d feat: 实现预算管理功能界面
1. 预算管理界面
   - 创建 BudgetScreen 预算管理主界面
   - 支持总览、分类预算、成员预算三个标签页
   - 实现预算状态可视化(进度条、超支提醒)
   - 预算项目的启用/禁用切换

2. 预算编辑功能
   - 创建 BudgetEditDialog 预算编辑对话框
   - 支持设置预算类型、金额、预警阈值
   - 分类预算和成员预算的选择器
   - 自动设置月度周期

3. 业务逻辑
   - 创建 BudgetViewModel 管理预算状态
   - 实现预算的创建、更新、删除功能
   - 预算状态的实时计算和更新

4. 导航集成
   - 在设置页面添加预算管理入口
   - 更新导航系统支持预算管理界面
   - 添加预算管理路由

5. 文档更新
   - 更新 README 版本历史
   - 标记预算管理功能为基本完成
   - 更新功能进度状态

注:界面已完成,待实现预算超支提醒和分析报告功能

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 23:09:38 +08:00
7fc76df829 docs: 更新 README 文件,反映最新的项目进度
- 标记月度记账开始日期功能为已完成
- 标记数据管理功能为已完成(包括备份加密)
- 更新预算管理功能状态为进行中
- 添加 v1.4 和 v1.5(开发中)版本历史
- 在主要特性中添加备份加密和自定义周期功能

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 22:50:05 +08:00
7933452ab5 Merge branch 'feature/encryption-budget' into develop 2025-07-19 22:31:57 +08:00
026df11933 feat: 实现备份加密功能和预算管理基础架构
1. 备份加密功能
   - 添加 EncryptionUtils 使用 Android Keystore 安全存储密钥
   - 修改导出功能支持 CSV 和 Excel 文件加密
   - 实现加密文件的自动解密导入
   - 在设置页面添加备份加密开关

2. 预算管理基础架构
   - 创建 Budget 数据模型,支持总预算、分类预算和成员预算
   - 创建 BudgetDao 提供数据库操作接口
   - 创建 BudgetRepository 实现预算业务逻辑
   - 更新数据库版本至 v6 并添加迁移

3. 其他改进
   - 创建 CLAUDE.md 文件提供项目指导
   - 修复编译错误和类型安全问题
   - 更新 FilePickerUtil 支持加密文件格式

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-19 22:26:17 +08:00
316176bf6a feat: 实现月度记账开始日期功能
- 添加 Settings 实体和 DAO 来持久化存储设置
- 创建 SettingsRepository 管理设置数据
- 添加数据库迁移从版本 4 到版本 5
- 在设置界面添加月度开始日期选择器(1-28号)
- 创建 DateUtils 工具类处理基于月度开始日期的日期计算
- 更新 HomeViewModel 和 AnalysisViewModel 使用月度开始日期进行统计
- 修复日期选择器中数字显示不完整的问题
2025-07-19 22:19:50 +08:00
bdf01f6bbe feat: 实现月度记账开始日期功能
- 添加 Settings 实体和 DAO 来持久化存储设置
- 创建 SettingsRepository 管理设置数据
- 添加数据库迁移从版本 4 到版本 5
- 在设置界面添加月度开始日期选择器(1-28号)
- 创建 DateUtils 工具类处理基于月度开始日期的日期计算
- 更新 HomeViewModel 和 AnalysisViewModel 使用月度开始日期进行统计
- 修复日期选择器中数字显示不完整的问题
2025-07-19 22:19:43 +08:00
2339e5b980 Merge pull request 'feat: 实现月度记账开始日期功能' (#4) from detached into develop
Reviewed-on: #4
2025-07-14 15:19:51 +08:00
f4f03ce0a4 feat: 实现月度记账开始日期功能
- 添加 Settings 实体和 DAO 来持久化存储设置
- 创建 SettingsRepository 管理设置数据
- 添加数据库迁移从版本 4 到版本 5
- 在设置界面添加月度开始日期选择器(1-28号)
- 创建 DateUtils 工具类处理基于月度开始日期的日期计算
- 更新 HomeViewModel 和 AnalysisViewModel 使用月度开始日期进行统计
- 修复日期选择器中数字显示不完整的问题
2025-07-14 15:17:47 +08:00
439080499b Revert "feat: 实现月度记账开始日期功能"
This reverts commit a86898011d.
2025-07-14 15:10:57 +08:00
a86898011d feat: 实现月度记账开始日期功能
- 添加 Settings 实体和 DAO 来持久化存储设置
- 创建 SettingsRepository 管理设置数据
- 添加数据库迁移从版本 4 到版本 5
- 在设置界面添加月度开始日期选择器(1-28号)
- 创建 DateUtils 工具类处理基于月度开始日期的日期计算
- 更新 HomeViewModel 和 AnalysisViewModel 使用月度开始日期进行统计
- 修复日期选择器中数字显示不完整的问题
- 创建 CLAUDE.md 文件记录项目开发指南

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-14 15:08:12 +08:00
4c1aa501e6 docs: 增加注释 2025-07-14 14:31:36 +08:00
8bc3e987aa docs: 新增功能需求
- 月度账单开始日期
2025-03-05 08:51:50 +08:00
0804791bd2 "End merge process" 2024-12-17 14:41:48 +08:00
5d5414d51d "Merge changes and update permissions" 2024-12-17 14:40:24 +08:00
046c6a6ae0 Merge remote-tracking branch 'origin/feature/icon' into feature/icon 2024-12-17 14:37:21 +08:00
1b0c6982e8 fix: 修复图标缺失错误 2024-12-17 14:36:54 +08:00
3080e98caa fix: 修复权限缺失问题 2024-12-17 14:36:26 +08:00
d0b3b9a663 fix: 夫妇图标缺失错误 2024-12-17 14:35:12 +08:00
0497e2503b fix: 修复图标显示不全问题 2024-12-17 14:10:11 +08:00
3c7b1dc610 feat: 增加数据备份功能
- 导出 CSV/Excel 功能
- 数据导入
- 数据迁移工具
- 定期自动备份
2024-12-17 13:47:57 +08:00
c517abce35 update: 修改README.md文件 2024-12-16 23:46:04 +08:00
4ade51c1df Revert "feat: 升级到 v1.3.0 版本"
This reverts commit f8e1a69214.
2024-12-16 23:44:48 +08:00
f8e1a69214 feat: 升级到 v1.3.0 版本
- 完成图标美化计划
- 增加分类和成员图标支持
- 更新 README.md 文档
2024-12-16 23:44:30 +08:00
9a0ed2ec7c feat: 升级到 v1.3.0 版本
- 完成图标美化计划
- 增加分类和成员图标支持
- 更新 README.md 文档
2024-12-16 23:40:17 +08:00
84d5b6c672 update: 修改icon文件 2024-12-16 16:00:24 +08:00
af8898e60f update: 新增默认数据 2024-12-10 14:08:07 +08:00
aad8b13a01 docs: 更新项目开源协议为 Apache License 2.0 2024-12-06 16:34:19 +08:00
bd60e62af3 fix: 修改构建版本号 2024-12-05 17:06:04 +08:00
119 changed files with 6243 additions and 663 deletions

View File

@@ -0,0 +1,12 @@
{
"permissions": {
"allow": [
"Bash(./gradlew:*)",
"Bash(git push:*)",
"Bash(git branch:*)",
"Bash(git add:*)",
"Bash(git commit:*)"
],
"deny": []
}
}

6
.idea/AndroidProjectSystem.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidProjectSystem">
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
</component>
</project>

View File

@@ -49,6 +49,9 @@
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewParameterProviderOnFirstParameter" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />

117
CLAUDE.md Normal file
View File

@@ -0,0 +1,117 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
轻记账是一个使用 Kotlin 和 Jetpack Compose 开发的 Android 记账应用,采用 MVVM 架构。项目强调隐私保护,完全离线运行。
## 常用命令
### 构建和运行
```bash
./gradlew build # 构建项目
./gradlew assembleDebug # 构建调试 APK
./gradlew assembleRelease # 构建发布 APK
./gradlew installDebug # 安装调试版本到设备
./gradlew clean # 清理构建产物
```
### 测试相关
```bash
./gradlew test # 运行单元测试
./gradlew connectedAndroidTest # 运行设备测试
```
## 架构概览
### MVVM 架构分层
- **Model 层**: Room 数据库实体 (`model/` 目录下的 BookkeepingRecord, Category, Member, Settings)
- **Data 层**: DAO 接口和 Repository 模式实现数据访问
- **ViewModel 层**: 每个功能模块独立的 ViewModel (HomeViewModel, AnalysisViewModel 等)
- **View 层**: Jetpack Compose UI包含 screens、components 和 dialogs
### 核心数据流
1. UI 层通过 ViewModel 发起数据请求
2. ViewModel 调用 Repository 获取数据
3. Repository 通过 DAO 访问 Room 数据库
4. 数据通过 Flow/StateFlow 响应式传递回 UI
### 数据库架构
- **主数据库**: BookkeepingDatabase (当前版本 5)
- **核心表**: bookkeeping_records, categories, members, settings
- **关键关系**: records 通过 memberId 关联 members 表
- **迁移策略**: 使用 Room 的 Migration 机制处理版本升级
### 导航架构
使用 Jetpack Navigation Compose主要页面
- HomeScreen: 主页记账列表
- AnalysisScreen: 数据分析图表
- AddRecordScreen: 添加/编辑记录
- CategoryManagementScreen: 分类管理
- MemberManagementScreen: 成员管理
- SettingsScreen: 设置页面
## 关键技术决策
### UI 框架
- 完全使用 Jetpack Compose 构建 UI
- Material 3 设计系统,支持深色/浅色主题
- 自定义主题色功能通过 ColorThemeDialog 实现
### 数据可视化
- 使用 MPAndroidChart 实现图表功能
- ChartManager 统一管理图表样式和行为
- 支持饼图和折线图两种展示方式
### 文件导入导出
- Apache POI 处理 Excel 文件
- OpenCSV 处理 CSV 文件
- FileUtils 提供统一的文件操作接口
### 图标系统
- 所有图标使用 Material Icons 和自定义矢量图标
- CategoryIcon 和 MemberIcon 枚举管理图标映射
- 支持动态图标选择和预览
## 开发注意事项
### 分支策略
- master: 稳定主分支
- develop: 开发分支
- feature/*: 功能开发
- release/*: 版本发布
- hotfix/*: 紧急修复
### 提交规范
使用约定式提交: `<type>: <description>`
- feat: 新功能
- fix: 修复 bug
- docs: 文档更新
- style: 代码格式
- refactor: 代码重构
- perf: 性能优化
- test: 测试相关
- build: 构建相关
### 重要功能模块
#### 月度记账开始日期 (Settings 中的 monthStartDay)
- 支持自定义每月记账的开始日期 (1-31)
- 影响月度统计和分析的日期范围计算
- 默认值为 1 (每月 1 日开始)
#### 加密功能 (EncryptionUtils)
- 预留的备份加密功能接口
- 使用 AES 加密算法
- 目前尚未集成到备份功能中
#### 默认数据初始化
- 首次启动时自动创建默认分类
- 包含常用的收入和支出分类
- 可通过 insertDefaultCategories() 查看默认分类列表
### 性能考虑
- 使用 Room 的 Flow 实现数据的响应式更新
- 图表数据计算在 ViewModel 中异步处理
- 大量数据导入时使用批量插入优化性能

167
LICENSE
View File

@@ -1,158 +1,73 @@
Creative Commons Attribution-NonCommercial 4.0 International
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Using Creative Commons Public Licenses
1. Definitions.
Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
Considerations for licensors: Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. More considerations for licensors.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
Considerations for the public: By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensors permission is not necessary for any reasonfor example, because of any applicable exception or limitation to copyrightthen that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. More considerations for the public.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
Creative Commons Attribution-NonCommercial 4.0 International Public License
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
Section 1 Definitions.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
a. Adapted Material means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
b. Adapter's License means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
c. Copyright and Similar Rights means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
d. Effective Technological Measures means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
e. Exceptions and Limitations means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
f. Licensed Material means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
g. Licensed Rights means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
h. Licensor means the individual(s) or entity(ies) granting rights under this Public License.
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
i. NonCommercial means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
j. Share means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
k. Sui Generis Database Rights means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
l. You means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
Section 2 Scope.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
a. License grant.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
END OF TERMS AND CONDITIONS
3. Term. The term of this Public License is specified in Section 6(a).
APPENDIX: How to apply the Apache License to your work.
4. Media and formats; technical modifications allowed. The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
5. Downstream recipients.
Copyright 2024 yovinchen
A. Offer from the Licensor Licensed Material. Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
B. No downstream restrictions. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
http://www.apache.org/licenses/LICENSE-2.0
6. No endorsement. Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this Public License.
3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes.
Section 3 License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified form), You must:
A. retain the following if it is supplied by the Licensor with the Licensed Material:
i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of warranties;
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's License You apply must not prevent recipients of the Adapted Material from complying with this Public License.
Section 4 Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only;
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
Section 5 Disclaimer of Warranties and Limitation of Liability.
a. Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
b. To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
Section 6 Term and Termination.
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
Section 7 Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
Section 8 Interpretation.
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at creativecommons.org/policies, Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
Creative Commons may be contacted at creativecommons.org.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

102
README.md
View File

@@ -6,6 +6,28 @@
本项目是一个使用 Kotlin 和 Jetpack Compose 开发的 Android 记账应用,采用 MVVM 架构,提供简洁直观的用户界面和丰富的记账功能。
## 🔥 功能亮点
### 📊 智能数据分析
- **月度/年度报表**:收支对比、储蓄率、日均消费等关键指标
- **详细分析报表**分类统计明细、TOP排行榜、可视化进度条
- **多维度统计**:支持按分类、成员、时间等多维度数据分析
### 💼 预算管理系统
- **多层级预算**:支持总预算、分类预算、成员预算
- **实时监控**:预算使用情况可视化,超支警告提醒
- **灵活配置**:可启用/禁用预算,自定义预警阈值
### 🔐 数据安全保障
- **备份加密**:使用 Android Keystore 加密导出文件
- **离线优先**:完全本地存储,无网络依赖
- **隐私保护**:极简权限,数据完全掌控
### 🎨 现代化设计
- **Material 3**:遵循最新设计规范
- **深色模式**:支持系统主题切换
- **响应式布局**:适配不同屏幕尺寸
## ⭐️ 主要特性
- 🔒 完全离线运行,无需网络连接
@@ -13,6 +35,10 @@
- 💰 支持收入和支出记录
- 👥 支持多人记账
- 📊 按日期和类别统计
- 🔐 备份文件加密保护
- 📅 自定义月度记账周期
- 💼 预算管理(基本完成)
- 📈 详细数据分析报表
## 🛠 技术栈
@@ -32,6 +58,7 @@
- [x] Material 3 设计界面
- [x] 深色/浅色主题切换
- [x] 主题色自定义
- [x] 月度记账开始日期
### 1. 成员系统 (已完成 🎉)
- [x] 成员添加/编辑/删除
@@ -42,31 +69,46 @@
### 2. 图表分析 (已完成 🎉)
- [x] 支出/收入趋势图表
- [x] 分类占比饼图
- [ ] 月度/年度报表
- [x] 月度/年度报表
- [x] 成员消费分析
- [x] 自定义统计周期
### 3. 数据管理 (进行中 🚀)
- [ ] 导出 CSV/Excel 功能
- [ ] 数据迁移工具
- [ ] 定期自动备份
- [ ] 备份加密功能
### 3 图标美化计划 (已完成 🎉)
- [x] 食品类图标 (餐饮、零食、饮料等)
- [x] 交通类图标 (公交、打车、加油等)
- [x] 购物类图标 (超市、数码、服装等)
- [x] 居住类图标 (房租、水电、物业等)
- [x] 医疗类图标 (药品、诊疗、保健等)
- [x] 娱乐类图标 (游戏、电影、旅游等)
- [x] 学习类图标 (书籍、课程、文具等)
- [x] 其他类图标 (礼物、捐赠、其他等)
- [x] 收入类图标 (工资、奖金、理财等)
- [x] 成员图标 (家人、朋友、同事等)
### 4. 预算管理 (计划中 💡)
- [ ] 月度预算设置
### 4. 数据管理 (已完成 🎉)
- [x] 导出 CSV/Excel 功能
- [x] 数据导入
- [x] 数据迁移工具
- [x] 定期自动备份
- [x] 备份加密功能
### 5. 预算管理 (基本完成 ✨)
- [x] 预算数据模型设计
- [x] 数据库架构实现
- [x] 预算管理界面
- [x] 月度预算设置
- [ ] 预算超支提醒
- [ ] 分类预算管理
- [ ] 成员预算管理
- [x] 分类预算管理
- [x] 成员预算管理
- [ ] 预算分析报告
### 5. 体验优化 (持续进行 🔄)
### 6. 体验优化 (持续进行 🔄)
- [x] 深色模式支持
- [ ] 手势操作优化
- [ ] 快速记账小组件
- [ ] 多语言支持
- [ ] 自定义主题
### 6. 性能提升 (持续进行 ⚡️)
### 7. 性能提升 (持续进行 ⚡️)
- [ ] 大数据量处理优化
- [ ] 启动速度优化
- [ ] 内存使用优化
@@ -102,6 +144,38 @@
## 📝 版本历史
### v1.5 (开发中)
- 预算管理功能
- 预算数据模型设计
- 支持总预算、分类预算、成员预算
- 数据库架构实现升级到版本6
- 预算管理界面设计
- 预算编辑对话框
- 预算状态可视化(进度条、超支提醒)
- 预算导航集成
- 数据分析优化
- 月度/年度报表组件
- 详细分析报表(分类统计明细)
- 收支对比、储蓄率、日均消费分析
- TOP分类排行榜金银铜奖牌设计
- 报表视图集成到分析页面
- 修复嵌套滚动组件崩溃问题
### v1.4
- 数据安全功能
- 备份文件加密使用Android Keystore
- 支持加密CSV/Excel导出
- 自动检测和解密加密备份
- 设置页面加密开关
- 月度记账优化
- 自定义月度开始日期1-28号
- 所有统计基于自定义周期
### v1.3
- 图标美化计划
- 增加图标美化
- 支持图标选择
### v1.2.0 - v1.2.4
- 分类数据可视化
- 支出/收入分类饼图展示
@@ -161,7 +235,7 @@
## 📄 许可证
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详细信息
本项目采用 Apache License 2.0 许可证 - 查看 [LICENSE](LICENSE) 文件了解详细信息
## 📮 联系方式

View File

@@ -16,8 +16,8 @@ android {
applicationId = "com.yovinchen.bookkeeping"
minSdk = 26
targetSdk = 34
versionCode = 5
versionName = "1.2.3"
versionCode = 6
versionName = "1.3.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
@@ -107,4 +107,9 @@ dependencies {
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
// CSV Excel 库
implementation("com.opencsv:opencsv:5.7.1")
implementation("org.apache.poi:poi:5.2.3")
implementation("org.apache.poi:poi-ooxml:5.2.3")
}

View File

@@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"

View File

@@ -1,9 +1,12 @@
package com.yovinchen.bookkeeping
import android.app.Activity
import android.net.Uri
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
@@ -19,17 +22,68 @@ import com.yovinchen.bookkeeping.model.ThemeMode
import com.yovinchen.bookkeeping.ui.components.predefinedColors
import com.yovinchen.bookkeeping.ui.navigation.MainNavigation
import com.yovinchen.bookkeeping.ui.theme.BookkeepingTheme
import com.yovinchen.bookkeeping.utils.FilePickerUtil
/**
* 全局文件选择器启动器
* 用于在整个应用程序中共享同一个文件选择器实例
*/
private var filePickerLauncher: ActivityResultLauncher<Array<String>>? = null
/**
* 获取预先注册的文件选择器启动器的扩展函数
*
* @return 预先注册的文件选择器启动器
* @throws IllegalStateException 如果文件选择器未初始化
*/
fun ComponentActivity.getPreregisteredFilePickerLauncher(): ActivityResultLauncher<Array<String>> {
return filePickerLauncher ?: throw IllegalStateException("FilePickerLauncher not initialized")
}
/**
* 应用程序的主活动
* 负责初始化应用界面和必要的系统组件
*/
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 设置系统窗口装饰,确保内容能够扩展到系统栏区域
WindowCompat.setDecorFitsSystemWindows(window, false)
// 预注册文件选择器,用于处理文件选择操作
filePickerLauncher = registerForActivityResult(
ActivityResultContracts.OpenDocument()
) { uri: Uri? ->
// 当用户选择文件后,调用工具类处理文件选择结果
FilePickerUtil.handleFileSelection(this, uri)
}
// 设置应用的主Compose内容
setContent {
BookkeepingApp()
}
}
}
/**
* 系统状态栏和导航栏颜色设置
* 根据当前主题模式设置系统UI元素的颜色和外观
*
* @param isDarkTheme 是否为暗色主题
*/
@Composable
private fun SystemBarColor(isDarkTheme: Boolean) {
val view = LocalView.current
if (!view.isInEditMode) {
// 获取当前主题的表面颜色用于系统栏
val surfaceColor = MaterialTheme.colorScheme.surface.toArgb()
val currentWindow = (view.context as? Activity)?.window
SideEffect {
currentWindow?.let { window ->
// 设置状态栏和导航栏颜色
window.statusBarColor = surfaceColor
window.navigationBarColor = surfaceColor
// 设置系统栏图标的亮暗模式,以确保在不同背景下的可见性
WindowCompat.getInsetsController(window, view).apply {
isAppearanceLightStatusBars = !isDarkTheme
isAppearanceLightNavigationBars = !isDarkTheme
@@ -39,27 +93,37 @@ private fun SystemBarColor(isDarkTheme: Boolean) {
}
}
/**
* 记账应用的主Compose函数
* 处理主题设置并启动主导航组件
*/
@Composable
fun BookkeepingApp() {
// 跟踪当前应用的主题模式状态
var themeMode by remember { mutableStateOf<ThemeMode>(ThemeMode.FOLLOW_SYSTEM) }
// 根据主题模式确定是否使用暗色主题
val isDarkTheme = when (themeMode) {
is ThemeMode.FOLLOW_SYSTEM -> isSystemInDarkTheme()
is ThemeMode.LIGHT -> false
is ThemeMode.DARK -> true
is ThemeMode.CUSTOM -> isSystemInDarkTheme()
is ThemeMode.FOLLOW_SYSTEM -> isSystemInDarkTheme() // 跟随系统设置
is ThemeMode.LIGHT -> false // 强制使用亮色主题
is ThemeMode.DARK -> true // 强制使用暗色主题
is ThemeMode.CUSTOM -> isSystemInDarkTheme() // 自定义主题下的基础亮暗模式仍跟随系统
}
// 处理自定义主题颜色方案
val customColorScheme = when (themeMode) {
is ThemeMode.CUSTOM -> {
// 从主题模式中提取自定义主色
val primaryColor = (themeMode as ThemeMode.CUSTOM).primaryColor
if (isDarkTheme) {
// 暗色模式下的自定义颜色方案
MaterialTheme.colorScheme.copy(
primary = primaryColor,
secondary = primaryColor.copy(alpha = 0.7f),
tertiary = primaryColor.copy(alpha = 0.5f)
)
} else {
// 亮色模式下的自定义颜色方案
MaterialTheme.colorScheme.copy(
primary = primaryColor,
secondary = primaryColor.copy(alpha = 0.7f),
@@ -67,37 +131,38 @@ fun BookkeepingApp() {
)
}
}
else -> null
else -> null // 非自定义主题模式使用默认颜色方案
}
// 应用主题到整个应用内容
BookkeepingTheme(
darkTheme = isDarkTheme,
customColorScheme = customColorScheme
) {
// 设置系统状态栏和导航栏颜色
SystemBarColor(isDarkTheme)
// 创建填充整个屏幕的基础Surface
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.surface
) {
// 启动主导航组件,并传递主题相关参数
MainNavigation(
currentTheme = themeMode,
onThemeChange = { themeMode = it }
onThemeChange = { themeMode = it } // 允许导航组件中的屏幕更改主题
)
}
}
}
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
BookkeepingApp()
}
}
}
/**
* 示例问候函数
* 仅用于开发预览和测试目的
*
* @param name 要显示的名称
* @param modifier 应用于Text组件的修饰符
*/
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
@@ -106,6 +171,9 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
)
}
/**
* Greeting组件的预览函数
*/
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
@@ -114,6 +182,9 @@ fun GreetingPreview() {
}
}
/**
* 整个应用的预览函数
*/
@Preview(showBackground = true)
@Composable
fun BookkeepingAppPreview() {

View File

@@ -8,18 +8,21 @@ import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.yovinchen.bookkeeping.R
import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.Budget
import com.yovinchen.bookkeeping.model.Category
import com.yovinchen.bookkeeping.model.Converters
import com.yovinchen.bookkeeping.model.Member
import com.yovinchen.bookkeeping.model.Settings
import com.yovinchen.bookkeeping.model.TransactionType
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@Database(
entities = [BookkeepingRecord::class, Category::class, Member::class],
version = 3,
entities = [BookkeepingRecord::class, Category::class, Member::class, Settings::class, Budget::class],
version = 6,
exportSchema = false
)
@TypeConverters(Converters::class)
@@ -27,6 +30,8 @@ abstract class BookkeepingDatabase : RoomDatabase() {
abstract fun bookkeepingDao(): BookkeepingDao
abstract fun categoryDao(): CategoryDao
abstract fun memberDao(): MemberDao
abstract fun settingsDao(): SettingsDao
abstract fun budgetDao(): BudgetDao
companion object {
private const val TAG = "BookkeepingDatabase"
@@ -38,14 +43,15 @@ abstract class BookkeepingDatabase : RoomDatabase() {
CREATE TABLE IF NOT EXISTS members (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT ''
description TEXT NOT NULL DEFAULT '',
icon INTEGER NOT NULL DEFAULT 0
)
""")
// 插入默认成员
db.execSQL("""
INSERT INTO members (name, description)
VALUES ('自己', '默认成员')
INSERT INTO members (name, description, icon)
VALUES ('自己', '默认成员', ${R.drawable.ic_member_boy_24dp})
""")
// 修改记账记录表添加成员ID字段
@@ -96,14 +102,15 @@ abstract class BookkeepingDatabase : RoomDatabase() {
CREATE TABLE IF NOT EXISTS categories_new (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL,
type TEXT NOT NULL
type TEXT NOT NULL,
icon INTEGER NOT NULL DEFAULT 0
)
""")
// 复制分类数据
db.execSQL("""
INSERT INTO categories_new (id, name, type)
SELECT id, name, type FROM categories
INSERT INTO categories_new (id, name, type, icon)
SELECT id, name, type, 0 FROM categories
""")
// 删除旧表
@@ -114,6 +121,59 @@ abstract class BookkeepingDatabase : RoomDatabase() {
}
}
private val MIGRATION_3_4 = object : Migration(3, 4) {
override fun migrate(db: SupportSQLiteDatabase) {
// 如果需要,在这里添加数据库迁移逻辑
// 由于这次更改可能只是schema hash的变化我们不需要实际的数据库更改
}
}
private val MIGRATION_4_5 = object : Migration(4, 5) {
override fun migrate(db: SupportSQLiteDatabase) {
// 创建设置表
db.execSQL("""
CREATE TABLE IF NOT EXISTS settings (
id INTEGER PRIMARY KEY NOT NULL DEFAULT 1,
monthStartDay INTEGER NOT NULL DEFAULT 1,
themeMode TEXT NOT NULL DEFAULT 'FOLLOW_SYSTEM',
autoBackupEnabled INTEGER NOT NULL DEFAULT 0,
autoBackupInterval INTEGER NOT NULL DEFAULT 7,
lastBackupTime INTEGER NOT NULL DEFAULT 0
)
""")
// 插入默认设置
db.execSQL("""
INSERT OR IGNORE INTO settings (id, monthStartDay, themeMode, autoBackupEnabled, autoBackupInterval, lastBackupTime)
VALUES (1, 1, 'FOLLOW_SYSTEM', 0, 7, 0)
""")
}
}
private val MIGRATION_5_6 = object : Migration(5, 6) {
override fun migrate(db: SupportSQLiteDatabase) {
// 创建预算表
db.execSQL("""
CREATE TABLE IF NOT EXISTS budgets (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
type TEXT NOT NULL,
categoryName TEXT,
memberId INTEGER,
amount REAL NOT NULL,
startDate INTEGER NOT NULL,
endDate INTEGER NOT NULL,
isEnabled INTEGER NOT NULL DEFAULT 1,
alertThreshold REAL NOT NULL DEFAULT 0.8,
createdAt INTEGER NOT NULL,
updatedAt INTEGER NOT NULL
)
""")
// 在 settings 表中添加 encryptBackup 列
db.execSQL("ALTER TABLE settings ADD COLUMN encryptBackup INTEGER NOT NULL DEFAULT 1")
}
}
@Volatile
private var INSTANCE: BookkeepingDatabase? = null
@@ -124,7 +184,7 @@ abstract class BookkeepingDatabase : RoomDatabase() {
BookkeepingDatabase::class.java,
"bookkeeping_database"
)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5, MIGRATION_5_6)
.addCallback(object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
@@ -133,31 +193,60 @@ abstract class BookkeepingDatabase : RoomDatabase() {
try {
val database = getDatabase(context)
// 初始化默认设置
database.settingsDao().apply {
updateSettings(Settings())
}
// 初始化默认成员
database.memberDao().apply {
if (getMemberCount() == 0) {
insertMember(Member(name = "自己", description = "默认成员"))
insertMember(Member(name = "自己", description = "默认成员", icon = R.drawable.ic_member_boy_24dp))
insertMember(Member(name = "老婆", description = "默认成员", icon = R.drawable.ic_member_girl_24dp))
insertMember(Member(name = "老公", description = "默认成员", icon = R.drawable.ic_member_boy_24dp))
insertMember(Member(name = "家庭", description = "默认成员", icon = R.drawable.ic_member_family_24dp))
insertMember(Member(name = "儿子", description = "默认成员", icon = R.drawable.ic_member_baby_boy_24dp))
insertMember(Member(name = "女儿", description = "默认成员", icon = R.drawable.ic_member_baby_girl_24dp))
insertMember(Member(name = "爸爸", description = "默认成员", icon = R.drawable.ic_member_father_24dp))
insertMember(Member(name = "妈妈", description = "默认成员", icon = R.drawable.ic_member_mother_24dp))
insertMember(Member(name = "爷爷", description = "默认成员", icon = R.drawable.ic_member_grandfather_24dp))
insertMember(Member(name = "奶奶", description = "默认成员", icon = R.drawable.ic_member_grandmother_24dp))
insertMember(Member(name = "外公", description = "默认成员", icon = R.drawable.ic_member_grandfather_24dp))
insertMember(Member(name = "外婆", description = "默认成员", icon = R.drawable.ic_member_grandmother_24dp))
insertMember(Member(name = "其他人", description = "默认成员", icon = R.drawable.ic_member_boy_24dp))
}
}
// 初始化默认分类
// 初始化默认分类
database.categoryDao().apply {
// 支出分类
insertCategory(Category(name = "餐饮", type = TransactionType.EXPENSE))
insertCategory(Category(name = "交通", type = TransactionType.EXPENSE))
insertCategory(Category(name = "购物", type = TransactionType.EXPENSE))
insertCategory(Category(name = "娱乐", type = TransactionType.EXPENSE))
insertCategory(Category(name = "居住", type = TransactionType.EXPENSE))
insertCategory(Category(name = "医疗", type = TransactionType.EXPENSE))
insertCategory(Category(name = "教育", type = TransactionType.EXPENSE))
insertCategory(Category(name = "其他支出", type = TransactionType.EXPENSE))
insertCategory(Category(name = "餐饮", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_food_24dp)) // "餐饮" to R.drawable.ic_category_food_24dp
insertCategory(Category(name = "交通", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_taxi_24dp)) // "交通" to R.drawable.ic_category_taxi_24dp
insertCategory(Category(name = "购物", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_supermarket_24dp)) // "购物" to R.drawable.ic_category_supermarket_24dp
insertCategory(Category(name = "娱乐", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_bar_24dp)) // "娱乐" to R.drawable.ic_category_bar_24dp
insertCategory(Category(name = "居住", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_hotel_24dp)) // "居住" to R.drawable.ic_category_hotel_24dp
insertCategory(Category(name = "医疗", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_medicine_24dp)) // "医疗" to R.drawable.ic_category_medicine_24dp
insertCategory(Category(name = "教育", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_training_24dp)) // "教育" to R.drawable.ic_category_training_24dp
insertCategory(Category(name = "宠物", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_pet_24dp)) // "宠物" to R.drawable.ic_category_pet_24dp
insertCategory(Category(name = "鲜花", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_flower_24dp)) // "鲜花" to R.drawable.ic_category_flower_24dp
insertCategory(Category(name = "外卖", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_delivery_24dp)) // "外卖" to R.drawable.ic_category_delivery_24dp
insertCategory(Category(name = "数码", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_digital_24dp)) // "数码" to R.drawable.ic_category_digital_24dp
insertCategory(Category(name = "化妆品", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_cosmetics_24dp)) // "化妆品" to R.drawable.ic_category_cosmetics_24dp
insertCategory(Category(name = "水果", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_fruit_24dp)) // "水果" to R.drawable.ic_category_fruit_24dp
insertCategory(Category(name = "零食", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_snack_24dp)) // "零食" to R.drawable.ic_category_snack_24dp
insertCategory(Category(name = "蔬菜", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_vegetable_24dp)) // "蔬菜" to R.drawable.ic_category_vegetable_24dp
insertCategory(Category(name = "会员", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_membership_24dp)) // "工资" to R.drawable.ic_category_membership_24dp
insertCategory(Category(name = "礼物", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_gift_24dp)) // "礼物" to R.drawable.ic_category_gift_24dp
insertCategory(Category(name = "其他支出", type = TransactionType.EXPENSE, icon = R.drawable.ic_category_more_24dp)) // "其他" to R.drawable.ic_category_more_24dp
// 收入分类
insertCategory(Category(name = "工资", type = TransactionType.INCOME, icon = R.drawable.ic_category_membership_24dp)) // "工资" to R.drawable.ic_category_membership_24dp
insertCategory(Category(name = "奖金", type = TransactionType.INCOME, icon = R.drawable.ic_category_gift_24dp)) // "奖金" to R.drawable.ic_category_gift_24dp
insertCategory(Category(name = "投资", type = TransactionType.INCOME, icon = R.drawable.ic_category_digital_24dp)) // "投资" to R.drawable.ic_category_digital_24dp
insertCategory(Category(name = "其他收入", type = TransactionType.INCOME, icon = R.drawable.ic_category_more_24dp)) // "其他" to R.drawable.ic_category_more_24dp
// 收入分类
insertCategory(Category(name = "工资", type = TransactionType.INCOME))
insertCategory(Category(name = "奖金", type = TransactionType.INCOME))
insertCategory(Category(name = "投资", type = TransactionType.INCOME))
insertCategory(Category(name = "其他收入", type = TransactionType.INCOME))
}
Log.d(TAG, "Default data initialized successfully")
} catch (e: Exception) {

View File

@@ -0,0 +1,105 @@
package com.yovinchen.bookkeeping.data
import androidx.room.*
import com.yovinchen.bookkeeping.model.Budget
import com.yovinchen.bookkeeping.model.BudgetType
import kotlinx.coroutines.flow.Flow
import java.util.Date
/**
* 预算数据访问对象
* 提供预算相关的数据库操作接口
*/
@Dao
interface BudgetDao {
/**
* 插入新预算
*/
@Insert
suspend fun insertBudget(budget: Budget): Long
/**
* 更新预算
*/
@Update
suspend fun updateBudget(budget: Budget)
/**
* 删除预算
*/
@Delete
suspend fun deleteBudget(budget: Budget)
/**
* 根据ID获取预算
*/
@Query("SELECT * FROM budgets WHERE id = :budgetId")
suspend fun getBudgetById(budgetId: Int): Budget?
/**
* 获取所有启用的预算
*/
@Query("SELECT * FROM budgets WHERE isEnabled = 1 ORDER BY type, amount DESC")
fun getAllEnabledBudgets(): Flow<List<Budget>>
/**
* 获取所有预算(包括禁用的)
*/
@Query("SELECT * FROM budgets ORDER BY type, amount DESC")
fun getAllBudgets(): Flow<List<Budget>>
/**
* 根据类型获取预算
*/
@Query("SELECT * FROM budgets WHERE type = :type AND isEnabled = 1")
fun getBudgetsByType(type: BudgetType): Flow<List<Budget>>
/**
* 获取总预算
*/
@Query("SELECT * FROM budgets WHERE type = 'TOTAL' AND isEnabled = 1 AND :date BETWEEN startDate AND endDate LIMIT 1")
suspend fun getTotalBudget(date: Date): Budget?
/**
* 获取指定分类的预算
*/
@Query("SELECT * FROM budgets WHERE type = 'CATEGORY' AND categoryName = :categoryName AND isEnabled = 1 AND :date BETWEEN startDate AND endDate LIMIT 1")
suspend fun getCategoryBudget(categoryName: String, date: Date): Budget?
/**
* 获取指定成员的预算
*/
@Query("SELECT * FROM budgets WHERE type = 'MEMBER' AND memberId = :memberId AND isEnabled = 1 AND :date BETWEEN startDate AND endDate LIMIT 1")
suspend fun getMemberBudget(memberId: Int, date: Date): Budget?
/**
* 获取当前有效的所有预算
*/
@Query("SELECT * FROM budgets WHERE isEnabled = 1 AND :date BETWEEN startDate AND endDate ORDER BY type, amount DESC")
fun getActiveBudgets(date: Date): Flow<List<Budget>>
/**
* 更新预算的启用状态
*/
@Query("UPDATE budgets SET isEnabled = :enabled, updatedAt = :updatedAt WHERE id = :budgetId")
suspend fun updateBudgetEnabled(budgetId: Int, enabled: Boolean, updatedAt: Date = Date())
/**
* 删除所有过期的预算(可选)
*/
@Query("DELETE FROM budgets WHERE endDate < :date AND isEnabled = 0")
suspend fun deleteExpiredBudgets(date: Date)
/**
* 获取指定日期范围内的分类预算
*/
@Query("SELECT * FROM budgets WHERE type = 'CATEGORY' AND isEnabled = 1 AND :date BETWEEN startDate AND endDate")
fun getCategoryBudgetsForDate(date: Date): Flow<List<Budget>>
/**
* 获取指定日期范围内的成员预算
*/
@Query("SELECT * FROM budgets WHERE type = 'MEMBER' AND isEnabled = 1 AND :date BETWEEN startDate AND endDate")
fun getMemberBudgetsForDate(date: Date): Flow<List<Budget>>
}

View File

@@ -0,0 +1,215 @@
package com.yovinchen.bookkeeping.data
import com.yovinchen.bookkeeping.model.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import java.util.Date
import javax.inject.Inject
import javax.inject.Singleton
/**
* 预算仓库类
* 提供预算相关的业务逻辑和数据访问
*/
class BudgetRepository(
private val budgetDao: BudgetDao,
private val bookkeepingDao: BookkeepingDao,
private val memberDao: MemberDao
) {
/**
* 创建新预算
*/
suspend fun createBudget(budget: Budget): Long {
return budgetDao.insertBudget(budget)
}
/**
* 更新预算
*/
suspend fun updateBudget(budget: Budget) {
budgetDao.updateBudget(budget.copy(updatedAt = Date()))
}
/**
* 删除预算
*/
suspend fun deleteBudget(budget: Budget) {
budgetDao.deleteBudget(budget)
}
/**
* 获取所有预算
*/
fun getAllBudgets(): Flow<List<Budget>> {
return budgetDao.getAllBudgets()
}
/**
* 获取所有启用的预算
*/
fun getAllEnabledBudgets(): Flow<List<Budget>> {
return budgetDao.getAllEnabledBudgets()
}
/**
* 获取当前有效的预算状态
*/
fun getActiveBudgetStatuses(date: Date = Date()): Flow<List<BudgetStatus>> {
return combine(
budgetDao.getActiveBudgets(date),
bookkeepingDao.getAllRecords(),
memberDao.getAllMembers()
) { budgets, records, members ->
budgets.map { budget ->
val spent = calculateSpent(budget, records, members, date)
val remaining = budget.amount - spent
val percentage = if (budget.amount > 0) spent / budget.amount else 0.0
BudgetStatus(
budget = budget,
spent = spent,
remaining = remaining,
percentage = percentage,
isOverBudget = spent > budget.amount,
isNearLimit = percentage >= budget.alertThreshold
)
}
}
}
/**
* 计算预算已花费金额
*/
private fun calculateSpent(
budget: Budget,
records: List<BookkeepingRecord>,
members: List<Member>,
currentDate: Date
): Double {
// 只计算支出类型的记录
val expenseRecords = records.filter {
it.type == TransactionType.EXPENSE &&
it.date >= budget.startDate &&
it.date <= budget.endDate &&
it.date <= currentDate
}
return when (budget.type) {
BudgetType.TOTAL -> {
// 总预算:计算所有支出
expenseRecords.sumOf { it.amount }
}
BudgetType.CATEGORY -> {
// 分类预算:计算指定分类的支出
expenseRecords
.filter { it.category == budget.categoryName }
.sumOf { it.amount }
}
BudgetType.MEMBER -> {
// 成员预算:计算指定成员的支出
expenseRecords
.filter { it.memberId == budget.memberId }
.sumOf { it.amount }
}
}
}
/**
* 获取总预算状态
*/
suspend fun getTotalBudgetStatus(date: Date = Date()): BudgetStatus? {
val budget = budgetDao.getTotalBudget(date) ?: return null
val records = bookkeepingDao.getAllRecords().first()
val members = memberDao.getAllMembers().first()
val spent = calculateSpent(budget, records, members, date)
val remaining = budget.amount - spent
val percentage = if (budget.amount > 0) spent / budget.amount else 0.0
return BudgetStatus(
budget = budget,
spent = spent,
remaining = remaining,
percentage = percentage,
isOverBudget = spent > budget.amount,
isNearLimit = percentage >= budget.alertThreshold
)
}
/**
* 获取分类预算状态
*/
fun getCategoryBudgetStatuses(date: Date = Date()): Flow<List<BudgetStatus>> {
return combine(
budgetDao.getCategoryBudgetsForDate(date),
bookkeepingDao.getAllRecords(),
memberDao.getAllMembers()
) { budgets, records, members ->
budgets.map { budget ->
val spent = calculateSpent(budget, records, members, date)
val remaining = budget.amount - spent
val percentage = if (budget.amount > 0) spent / budget.amount else 0.0
BudgetStatus(
budget = budget,
spent = spent,
remaining = remaining,
percentage = percentage,
isOverBudget = spent > budget.amount,
isNearLimit = percentage >= budget.alertThreshold
)
}
}
}
/**
* 获取成员预算状态
*/
fun getMemberBudgetStatuses(date: Date = Date()): Flow<List<BudgetStatus>> {
return combine(
budgetDao.getMemberBudgetsForDate(date),
bookkeepingDao.getAllRecords(),
memberDao.getAllMembers()
) { budgets, records, members ->
budgets.map { budget ->
val spent = calculateSpent(budget, records, members, date)
val remaining = budget.amount - spent
val percentage = if (budget.amount > 0) spent / budget.amount else 0.0
BudgetStatus(
budget = budget,
spent = spent,
remaining = remaining,
percentage = percentage,
isOverBudget = spent > budget.amount,
isNearLimit = percentage >= budget.alertThreshold
)
}
}
}
/**
* 检查是否有预算超支或接近限制
*/
suspend fun checkBudgetAlerts(date: Date = Date()): List<BudgetStatus> {
val allStatuses = getActiveBudgetStatuses(date).first()
return allStatuses.filter { it.isOverBudget || it.isNearLimit }
}
/**
* 更新预算启用状态
*/
suspend fun updateBudgetEnabled(budgetId: Int, enabled: Boolean) {
budgetDao.updateBudgetEnabled(budgetId, enabled)
}
/**
* 清理过期的禁用预算
*/
suspend fun cleanupExpiredBudgets() {
budgetDao.deleteExpiredBudgets(Date())
}
}

View File

@@ -1,6 +1,7 @@
package com.yovinchen.bookkeeping.data
import androidx.room.TypeConverter
import com.yovinchen.bookkeeping.model.BudgetType
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
@@ -29,4 +30,14 @@ class Converters {
fun toDate(timestamp: String?): Date? {
return timestamp?.let { Date(it.toLong()) }
}
@TypeConverter
fun fromBudgetType(budgetType: BudgetType?): String? {
return budgetType?.name
}
@TypeConverter
fun toBudgetType(budgetType: String?): BudgetType? {
return budgetType?.let { BudgetType.valueOf(it) }
}
}

View File

@@ -0,0 +1,35 @@
package com.yovinchen.bookkeeping.data
import androidx.room.*
import com.yovinchen.bookkeeping.model.Settings
import kotlinx.coroutines.flow.Flow
@Dao
interface SettingsDao {
@Query("SELECT * FROM settings WHERE id = 1")
fun getSettings(): Flow<Settings?>
@Query("SELECT * FROM settings WHERE id = 1")
suspend fun getSettingsOnce(): Settings?
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun updateSettings(settings: Settings)
@Query("UPDATE settings SET monthStartDay = :day WHERE id = 1")
suspend fun updateMonthStartDay(day: Int)
@Query("UPDATE settings SET themeMode = :mode WHERE id = 1")
suspend fun updateThemeMode(mode: String)
@Query("UPDATE settings SET autoBackupEnabled = :enabled WHERE id = 1")
suspend fun updateAutoBackupEnabled(enabled: Boolean)
@Query("UPDATE settings SET autoBackupInterval = :interval WHERE id = 1")
suspend fun updateAutoBackupInterval(interval: Int)
@Query("UPDATE settings SET lastBackupTime = :time WHERE id = 1")
suspend fun updateLastBackupTime(time: Long)
@Query("UPDATE settings SET encryptBackup = :encrypt WHERE id = 1")
suspend fun updateEncryptBackup(encrypt: Boolean)
}

View File

@@ -0,0 +1,45 @@
package com.yovinchen.bookkeeping.data
import com.yovinchen.bookkeeping.model.Settings
import kotlinx.coroutines.flow.Flow
class SettingsRepository(private val settingsDao: SettingsDao) {
fun getSettings(): Flow<Settings?> = settingsDao.getSettings()
suspend fun getSettingsOnce(): Settings {
return settingsDao.getSettingsOnce() ?: Settings()
}
suspend fun updateSettings(settings: Settings) {
settingsDao.updateSettings(settings)
}
suspend fun updateMonthStartDay(day: Int) {
// 确保日期在有效范围内 (1-28)
val validDay = day.coerceIn(1, 28)
settingsDao.updateMonthStartDay(validDay)
}
suspend fun updateThemeMode(mode: String) {
settingsDao.updateThemeMode(mode)
}
suspend fun updateAutoBackupEnabled(enabled: Boolean) {
settingsDao.updateAutoBackupEnabled(enabled)
}
suspend fun updateAutoBackupInterval(interval: Int) {
settingsDao.updateAutoBackupInterval(interval)
}
suspend fun updateLastBackupTime(time: Long) {
settingsDao.updateLastBackupTime(time)
}
suspend fun ensureSettingsExist() {
if (settingsDao.getSettingsOnce() == null) {
settingsDao.updateSettings(Settings())
}
}
}

View File

@@ -1,7 +1,13 @@
package com.yovinchen.bookkeeping.model
/**
* 分析类型枚举
* 定义记账应用中不同的数据分析视图类型
*
* 用于在数据分析模块中区分不同的分析维度和图表类型
*/
enum class AnalysisType {
EXPENSE,
INCOME,
TREND
EXPENSE, // 支出分析,用于分析用户的支出情况
INCOME, // 收入分析,用于分析用户的收入情况
TREND // 趋势分析,用于分析用户收支随时间的变化趋势
}

View File

@@ -9,32 +9,71 @@ import androidx.room.TypeConverters
import com.yovinchen.bookkeeping.model.Member
import java.util.Date
/**
* 交易类型枚举
* 定义记账记录的交易类型
*/
enum class TransactionType {
INCOME, EXPENSE
INCOME, // 收入
EXPENSE // 支出
}
/**
* Room数据库类型转换器
* 用于在数据库中存储和检索复杂类型
*/
class Converters {
/**
* 将时间戳转换为Date对象
*
* @param value 时间戳(毫秒)
* @return 对应的Date对象如果输入为null则返回null
*/
@TypeConverter
fun fromTimestamp(value: Long?): Date? {
return value?.let { Date(it) }
}
/**
* 将Date对象转换为时间戳
*
* @param date Date对象
* @return 对应的时间戳毫秒如果输入为null则返回null
*/
@TypeConverter
fun dateToTimestamp(date: Date?): Long? {
return date?.time
}
/**
* 将字符串转换为TransactionType枚举
*
* @param value 交易类型的字符串表示
* @return 对应的TransactionType枚举值
*/
@TypeConverter
fun fromTransactionType(value: String): TransactionType {
return enumValueOf<TransactionType>(value)
}
/**
* 将TransactionType枚举转换为字符串
*
* @param type TransactionType枚举值
* @return 对应的字符串表示
*/
@TypeConverter
fun transactionTypeToString(type: TransactionType): String {
return type.name
}
}
/**
* 记账记录实体类
* 用于在Room数据库中存储用户的收支记录
*
* 该实体与Member实体存在外键关系表示每条记录可以关联到一个家庭成员
*/
@Entity(
tableName = "bookkeeping_records",
foreignKeys = [
@@ -42,21 +81,21 @@ class Converters {
entity = Member::class,
parentColumns = ["id"],
childColumns = ["memberId"],
onDelete = ForeignKey.SET_NULL
onDelete = ForeignKey.SET_NULL // 当关联的成员被删除时将此字段设为NULL
)
],
indices = [
Index(value = ["memberId"])
Index(value = ["memberId"]) // 在memberId上创建索引以提高查询性能
]
)
@TypeConverters(Converters::class)
@TypeConverters(Converters::class) // 应用类型转换器
data class BookkeepingRecord(
@PrimaryKey(autoGenerate = true)
val id: Long = 0,
val amount: Double,
val type: TransactionType,
val category: String,
val description: String,
val date: Date,
val memberId: Int? = null // 可为空表示未指定成员
val id: Long = 0, // 记录ID自动生成
val amount: Double, // 金额
val type: TransactionType, // 交易类型(收入或支出)
val category: String, // 分类
val description: String, // 描述
val date: Date, // 日期
val memberId: Int? = null // 关联的成员ID可为空表示未指定成员
)

View File

@@ -0,0 +1,86 @@
package com.yovinchen.bookkeeping.model
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.util.Date
/**
* 预算实体类
* 用于设置和跟踪月度预算、分类预算和成员预算
*/
@Entity(tableName = "budgets")
data class Budget(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
/**
* 预算类型TOTAL总预算, CATEGORY分类预算, MEMBER成员预算
*/
val type: BudgetType,
/**
* 预算关联的分类名称(仅在 type 为 CATEGORY 时使用)
*/
val categoryName: String? = null,
/**
* 预算关联的成员ID仅在 type 为 MEMBER 时使用)
*/
val memberId: Int? = null,
/**
* 预算金额
*/
val amount: Double,
/**
* 预算生效开始日期
*/
val startDate: Date,
/**
* 预算生效结束日期
*/
val endDate: Date,
/**
* 是否启用此预算
*/
val isEnabled: Boolean = true,
/**
* 提醒阈值(百分比,如 0.8 表示达到 80% 时提醒)
*/
val alertThreshold: Double = 0.8,
/**
* 创建时间
*/
val createdAt: Date = Date(),
/**
* 更新时间
*/
val updatedAt: Date = Date()
)
/**
* 预算类型枚举
*/
enum class BudgetType {
TOTAL, // 总预算
CATEGORY, // 分类预算
MEMBER // 成员预算
}
/**
* 预算状态数据类,用于展示预算使用情况
*/
data class BudgetStatus(
val budget: Budget,
val spent: Double, // 已花费金额
val remaining: Double, // 剩余金额
val percentage: Double, // 使用百分比
val isOverBudget: Boolean, // 是否超预算
val isNearLimit: Boolean // 是否接近预算限制
)

View File

@@ -3,10 +3,18 @@ package com.yovinchen.bookkeeping.model
import androidx.room.Entity
import androidx.room.PrimaryKey
/**
* 交易分类实体类
* 用于在Room数据库中存储收支分类信息
*
* 在记账应用中,每条记账记录都属于某个分类,
* 如"餐饮"、"交通"、"工资"等,便于用户对支出和收入进行分类统计
*/
@Entity(tableName = "categories")
data class Category(
@PrimaryKey(autoGenerate = true)
val id: Long = 0,
val name: String,
val type: TransactionType
val id: Long = 0, // 分类ID自动生成
val name: String, // 分类名称
val type: TransactionType, // 分类关联的交易类型(收入或支出)
val icon: Int? = null // 分类图标资源ID可选默认为null
)

View File

@@ -1,8 +1,14 @@
package com.yovinchen.bookkeeping.model
/**
* 分类统计数据类
* 用于表示某个分类的统计信息,通常用于数据分析和图表展示
*
* 该类不是数据库实体,而是从数据库查询结果中聚合生成的统计数据
*/
data class CategoryStat(
val category: String,
val amount: Double,
val count: Int = 0,
val percentage: Double = 0.0
val category: String, // 分类名称
val amount: Double, // 该分类的总金额
val count: Int = 0, // 该分类下的记录数量
val percentage: Double = 0.0 // 该分类金额占总金额的百分比0.0-100.0
)

View File

@@ -3,10 +3,18 @@ package com.yovinchen.bookkeeping.model
import androidx.room.Entity
import androidx.room.PrimaryKey
/**
* 家庭成员实体类
* 用于在Room数据库中存储家庭成员信息
*
* 在记账应用中,每条记账记录可以关联到特定的家庭成员,
* 以便追踪不同成员的收支情况
*/
@Entity(tableName = "members")
data class Member(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val name: String,
val description: String = "" // 可选的描述信息
val id: Int = 0, // 成员ID自动生成
val name: String, // 成员姓名
val description: String = "", // 成员描述信息,可选,默认为空字符串
val icon: Int? = null // 成员图标资源ID可选默认为null
)

View File

@@ -2,16 +2,39 @@ package com.yovinchen.bookkeeping.model
import androidx.room.ColumnInfo
/**
* 家庭成员统计数据类
* 用于表示某个成员的统计信息,通常用于数据分析和图表展示
*
* 该类不是数据库实体,而是通过数据库查询直接映射的结果类,
* 表示按成员分组的聚合数据
*/
data class MemberStat(
/**
* 成员名称
* 映射数据库查询结果中的member列
*/
@ColumnInfo(name = "member")
val member: String,
/**
* 该成员的总金额
* 映射数据库查询结果中的amount列
*/
@ColumnInfo(name = "amount")
val amount: Double,
/**
* 该成员下的记录数量
* 映射数据库查询结果中的count列
*/
@ColumnInfo(name = "count")
val count: Int,
/**
* 该成员金额占总金额的百分比0.0-100.0
* 映射数据库查询结果中的percentage列
*/
@ColumnInfo(name = "percentage")
val percentage: Double = 0.0
)

View File

@@ -0,0 +1,15 @@
package com.yovinchen.bookkeeping.model
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "settings")
data class Settings(
@PrimaryKey val id: Int = 1,
val monthStartDay: Int = 1, // 月度开始日期1-28默认为1号
val themeMode: String = "FOLLOW_SYSTEM", // 主题模式FOLLOW_SYSTEM, LIGHT, DARK
val autoBackupEnabled: Boolean = false, // 自动备份开关
val autoBackupInterval: Int = 7, // 自动备份间隔(天)
val lastBackupTime: Long = 0L, // 上次备份时间
val encryptBackup: Boolean = true // 备份加密开关,默认开启
)

View File

@@ -2,9 +2,35 @@ package com.yovinchen.bookkeeping.model
import androidx.compose.ui.graphics.Color
/**
* 主题模式密封类
* 用于表示应用程序的不同主题设置选项
* 通过密封类实现,限制可能的主题模式类型
*/
sealed class ThemeMode {
/**
* 跟随系统主题模式
* 应用将根据设备系统的暗色/亮色主题设置自动调整
*/
object FOLLOW_SYSTEM : ThemeMode()
/**
* 固定亮色主题模式
* 无论设备系统设置如何,应用将始终使用亮色主题
*/
object LIGHT : ThemeMode()
/**
* 固定暗色主题模式
* 无论设备系统设置如何,应用将始终使用暗色主题
*/
object DARK : ThemeMode()
/**
* 自定义主题模式
* 允许用户选择自定义的主题颜色
*
* @property primaryColor 用户选择的主要颜色,将影响应用的主色调
*/
data class CUSTOM(val primaryColor: Color) : ThemeMode()
}

View File

@@ -0,0 +1,302 @@
package com.yovinchen.bookkeeping.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.TransactionType
import java.text.NumberFormat
import java.time.YearMonth
import java.time.format.DateTimeFormatter
import java.util.*
/**
* 详细分析报表组件
* 显示按分类统计的详细信息
*/
@Composable
fun DetailedAnalysisReport(
records: List<BookkeepingRecord>,
startMonth: YearMonth,
endMonth: YearMonth,
modifier: Modifier = Modifier
) {
val currencyFormatter = NumberFormat.getCurrencyInstance(Locale.CHINA)
// 按类型分组
val incomeRecords = records.filter { it.type == TransactionType.INCOME }
val expenseRecords = records.filter { it.type == TransactionType.EXPENSE }
// 按分类统计
val incomeByCategory = incomeRecords.groupBy { it.category }
.mapValues { it.value.sumOf { record -> record.amount } }
.toList()
.sortedByDescending { it.second }
val expenseByCategory = expenseRecords.groupBy { it.category }
.mapValues { it.value.sumOf { record -> record.amount } }
.toList()
.sortedByDescending { it.second }
// 总收入和总支出
val totalIncome = incomeRecords.sumOf { it.amount }
val totalExpense = expenseRecords.sumOf { it.amount }
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// 时间范围标题
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 2.dp)
) {
Text(
text = if (startMonth == endMonth) {
"统计期间:${startMonth.format(DateTimeFormatter.ofPattern("yyyy年MM月"))}"
} else {
"统计期间:${startMonth.format(DateTimeFormatter.ofPattern("yyyy年MM月"))}${endMonth.format(DateTimeFormatter.ofPattern("yyyy年MM月"))}"
},
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(16.dp),
textAlign = TextAlign.Center
)
}
// 支出分类详情
if (expenseByCategory.isNotEmpty()) {
CategoryDetailCard(
title = "支出分类明细",
categoryData = expenseByCategory,
total = totalExpense,
color = MaterialTheme.colorScheme.error,
currencyFormatter = currencyFormatter
)
}
// 收入分类详情
if (incomeByCategory.isNotEmpty()) {
CategoryDetailCard(
title = "收入分类明细",
categoryData = incomeByCategory,
total = totalIncome,
color = MaterialTheme.colorScheme.primary,
currencyFormatter = currencyFormatter
)
}
// 分类占比前5名
if (expenseByCategory.isNotEmpty()) {
TopCategoriesCard(
title = "支出TOP5",
categoryData = expenseByCategory.take(5),
total = totalExpense,
color = MaterialTheme.colorScheme.error,
currencyFormatter = currencyFormatter
)
}
}
}
/**
* 分类详情卡片
*/
@Composable
private fun CategoryDetailCard(
title: String,
categoryData: List<Pair<String, Double>>,
total: Double,
color: Color,
currencyFormatter: NumberFormat
) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold,
color = color,
modifier = Modifier.padding(bottom = 16.dp)
)
// 总计
Row(
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "总计",
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold
)
Text(
text = currencyFormatter.format(total),
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold,
color = color
)
}
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
// 分类列表
categoryData.forEach { (category, amount) ->
val percentage = if (total > 0) (amount / total * 100) else 0.0
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = category,
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "${String.format("%.1f", percentage)}%",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
Text(
text = currencyFormatter.format(amount),
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Medium
)
}
// 进度条
LinearProgressIndicator(
progress = (percentage / 100).toFloat(),
modifier = Modifier
.fillMaxWidth()
.height(4.dp)
.clip(RoundedCornerShape(2.dp)),
color = color.copy(alpha = 0.8f),
trackColor = color.copy(alpha = 0.2f)
)
}
}
}
}
/**
* TOP分类卡片
*/
@Composable
private fun TopCategoriesCard(
title: String,
categoryData: List<Pair<String, Double>>,
total: Double,
color: Color,
currencyFormatter: NumberFormat
) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.secondaryContainer
)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(bottom = 12.dp)
)
categoryData.forEachIndexed { index, (category, amount) ->
val percentage = if (total > 0) (amount / total * 100) else 0.0
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(
modifier = Modifier.weight(1f),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
// 排名
Box(
modifier = Modifier
.size(24.dp)
.clip(RoundedCornerShape(12.dp))
.background(
when (index) {
0 -> Color(0xFFFFD700) // 金色
1 -> Color(0xFFC0C0C0) // 银色
2 -> Color(0xFFCD7F32) // 铜色
else -> MaterialTheme.colorScheme.surfaceVariant
}
),
contentAlignment = Alignment.Center
) {
Text(
text = "${index + 1}",
style = MaterialTheme.typography.labelSmall,
fontWeight = FontWeight.Bold,
color = if (index < 3) Color.White else MaterialTheme.colorScheme.onSurfaceVariant
)
}
Text(
text = category,
style = MaterialTheme.typography.bodyMedium,
fontWeight = if (index == 0) FontWeight.Bold else FontWeight.Normal
)
}
Column(
horizontalAlignment = Alignment.End
) {
Text(
text = currencyFormatter.format(amount),
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Medium
)
Text(
text = "${String.format("%.1f", percentage)}%",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
}
}
}

View File

@@ -0,0 +1,258 @@
package com.yovinchen.bookkeeping.ui.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.TransactionType
import java.text.NumberFormat
import java.time.LocalDateTime
import java.time.YearMonth
import java.time.format.DateTimeFormatter
import java.util.*
/**
* 月度/年度报表组件
* 显示收支对比、盈余情况等统计信息
*/
@Composable
fun MonthlyYearlyReport(
records: List<BookkeepingRecord>,
period: String, // "月度" 或 "年度"
startMonth: YearMonth,
endMonth: YearMonth,
modifier: Modifier = Modifier
) {
val totalIncome = records
.filter { it.type == TransactionType.INCOME }
.sumOf { it.amount }
val totalExpense = records
.filter { it.type == TransactionType.EXPENSE }
.sumOf { it.amount }
val balance = totalIncome - totalExpense
val savingsRate = if (totalIncome > 0) {
((totalIncome - totalExpense) / totalIncome * 100).coerceAtLeast(0.0)
} else 0.0
Card(
modifier = modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// 标题
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "$period 报表",
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold
)
Text(
text = if (startMonth == endMonth) {
startMonth.format(DateTimeFormatter.ofPattern("yyyy年MM月"))
} else {
"${startMonth.format(DateTimeFormatter.ofPattern("yyyy年MM月"))} - ${endMonth.format(DateTimeFormatter.ofPattern("yyyy年MM月"))}"
},
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
HorizontalDivider()
// 收支对比
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
// 收入
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.weight(1f)
) {
Text(
text = "总收入",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = formatCurrency(totalIncome),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)
}
// 分隔线
Box(
modifier = Modifier
.width(1.dp)
.height(40.dp)
.background(MaterialTheme.colorScheme.outlineVariant)
)
// 支出
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.weight(1f)
) {
Text(
text = "总支出",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = formatCurrency(totalExpense),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.error
)
}
}
// 盈余情况
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = if (balance >= 0) {
MaterialTheme.colorScheme.primaryContainer
} else {
MaterialTheme.colorScheme.errorContainer
}
)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(12.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = if (balance >= 0) "盈余" else "亏损",
style = MaterialTheme.typography.bodyMedium,
color = if (balance >= 0) {
MaterialTheme.colorScheme.onPrimaryContainer
} else {
MaterialTheme.colorScheme.onErrorContainer
}
)
Text(
text = formatCurrency(kotlin.math.abs(balance)),
style = MaterialTheme.typography.headlineSmall,
fontWeight = FontWeight.Bold,
color = if (balance >= 0) {
MaterialTheme.colorScheme.onPrimaryContainer
} else {
MaterialTheme.colorScheme.onErrorContainer
}
)
}
}
// 储蓄率
if (totalIncome > 0) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "储蓄率",
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.weight(1f)
)
Box(
modifier = Modifier.weight(2f)
) {
LinearProgressIndicator(
progress = (savingsRate / 100).toFloat().coerceIn(0f, 1f),
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
.clip(RoundedCornerShape(4.dp)),
color = when {
savingsRate >= 30 -> MaterialTheme.colorScheme.primary
savingsRate >= 10 -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.error
}
)
}
Text(
text = "${String.format("%.1f", savingsRate)}%",
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(start = 8.dp),
color = when {
savingsRate >= 30 -> MaterialTheme.colorScheme.primary
savingsRate >= 10 -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.error
}
)
}
}
// 日均消费
val dayCount = if (period == "月度") {
// 计算月度天数
java.time.temporal.ChronoUnit.DAYS.between(
startMonth.atDay(1),
endMonth.atEndOfMonth()
) + 1
} else {
// 计算年度天数
java.time.temporal.ChronoUnit.DAYS.between(
startMonth.atDay(1),
endMonth.atEndOfMonth()
) + 1
}
val dailyAverage = if (dayCount > 0) totalExpense / dayCount else 0.0
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = "日均消费",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = formatCurrency(dailyAverage),
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Bold
)
}
}
}
}
/**
* 格式化货币
*/
private fun formatCurrency(amount: Double): String {
val format = NumberFormat.getCurrencyInstance(Locale.CHINA)
return format.format(amount)
}

View File

@@ -6,10 +6,14 @@ import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.Member
import com.yovinchen.bookkeeping.model.TransactionType
import com.yovinchen.bookkeeping.utils.IconManager
import java.text.SimpleDateFormat
import java.util.*
@@ -24,6 +28,7 @@ fun RecordItem(
var showDeleteDialog by remember { mutableStateOf(false) }
val timeFormat = remember { SimpleDateFormat("HH:mm", Locale.getDefault()) }
val member = members.find { it.id == record.memberId }
val categoryIcon = IconManager.getCategoryIconVector(record.category)
Card(
modifier = modifier
@@ -36,9 +41,20 @@ fun RecordItem(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
// 左侧分类图标
if (categoryIcon != null) {
Icon(
imageVector = categoryIcon,
contentDescription = record.category,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
}
// 中间内容区域
Column(
modifier = Modifier.weight(1f)
) {
@@ -64,7 +80,7 @@ fun RecordItem(
)
}
// 金额显示
// 右侧金额显示
Text(
text = String.format("%.2f", record.amount),
style = MaterialTheme.typography.titleMedium,

View File

@@ -0,0 +1,223 @@
package com.yovinchen.bookkeeping.ui.dialog
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.yovinchen.bookkeeping.model.*
import java.util.*
/**
* 预算编辑对话框
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BudgetEditDialog(
budget: Budget? = null,
categories: List<Category>,
members: List<Member>,
onDismiss: () -> Unit,
onConfirm: (Budget) -> Unit
) {
var selectedType by remember { mutableStateOf(budget?.type ?: BudgetType.TOTAL) }
var amount by remember { mutableStateOf(budget?.amount?.toString() ?: "") }
var selectedCategory by remember { mutableStateOf(budget?.categoryName) }
var selectedMemberId by remember { mutableStateOf(budget?.memberId) }
var alertThreshold by remember { mutableStateOf((budget?.alertThreshold ?: 0.8) * 100) }
AlertDialog(
onDismissRequest = onDismiss,
title = {
Text(if (budget == null) "添加预算" else "编辑预算")
},
text = {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// 预算类型选择
Text(
text = "预算类型",
style = MaterialTheme.typography.labelMedium
)
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
FilterChip(
selected = selectedType == BudgetType.TOTAL,
onClick = { selectedType = BudgetType.TOTAL },
label = { Text("总预算") }
)
FilterChip(
selected = selectedType == BudgetType.CATEGORY,
onClick = { selectedType = BudgetType.CATEGORY },
label = { Text("分类预算") }
)
FilterChip(
selected = selectedType == BudgetType.MEMBER,
onClick = { selectedType = BudgetType.MEMBER },
label = { Text("成员预算") }
)
}
// 金额输入
OutlinedTextField(
value = amount,
onValueChange = { amount = it.filter { char -> char.isDigit() || char == '.' } },
label = { Text("预算金额") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
modifier = Modifier.fillMaxWidth(),
singleLine = true
)
// 分类选择(仅在分类预算时显示)
if (selectedType == BudgetType.CATEGORY) {
var expanded by remember { mutableStateOf(false) }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
OutlinedTextField(
value = selectedCategory ?: "",
onValueChange = {},
label = { Text("选择分类") },
readOnly = true,
modifier = Modifier
.fillMaxWidth()
.menuAnchor(),
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
}
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
categories.forEach { category ->
DropdownMenuItem(
text = { Text(category.name) },
onClick = {
selectedCategory = category.name
expanded = false
}
)
}
}
}
}
// 成员选择(仅在成员预算时显示)
if (selectedType == BudgetType.MEMBER) {
var expanded by remember { mutableStateOf(false) }
val selectedMember = members.find { it.id == selectedMemberId }
ExposedDropdownMenuBox(
expanded = expanded,
onExpandedChange = { expanded = !expanded }
) {
OutlinedTextField(
value = selectedMember?.name ?: "",
onValueChange = {},
label = { Text("选择成员") },
readOnly = true,
modifier = Modifier
.fillMaxWidth()
.menuAnchor(),
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
}
)
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false }
) {
members.forEach { member ->
DropdownMenuItem(
text = { Text(member.name) },
onClick = {
selectedMemberId = member.id
expanded = false
}
)
}
}
}
}
// 预警阈值
Column {
Text(
text = "预警阈值: ${alertThreshold.toInt()}%",
style = MaterialTheme.typography.labelMedium
)
Slider(
value = alertThreshold.toFloat(),
onValueChange = { alertThreshold = it.toDouble() },
valueRange = 50f..95f,
steps = 8,
modifier = Modifier.fillMaxWidth()
)
Text(
text = "当使用金额达到预算的 ${alertThreshold.toInt()}% 时提醒",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
},
confirmButton = {
TextButton(
onClick = {
val amountValue = amount.toDoubleOrNull()
if (amountValue != null && amountValue > 0) {
val calendar = Calendar.getInstance()
val startDate = budget?.startDate ?: calendar.time
// 设置结束日期为当月最后一天
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH))
calendar.set(Calendar.HOUR_OF_DAY, 23)
calendar.set(Calendar.MINUTE, 59)
calendar.set(Calendar.SECOND, 59)
val endDate = calendar.time
val newBudget = Budget(
id = budget?.id ?: 0,
type = selectedType,
amount = amountValue,
categoryName = if (selectedType == BudgetType.CATEGORY) selectedCategory else null,
memberId = if (selectedType == BudgetType.MEMBER) selectedMemberId else null,
startDate = startDate,
endDate = endDate,
alertThreshold = alertThreshold / 100,
isEnabled = budget?.isEnabled ?: true,
createdAt = budget?.createdAt ?: Date(),
updatedAt = Date()
)
onConfirm(newBudget)
}
},
enabled = amount.toDoubleOrNull() != null && amount.toDouble() > 0 &&
(selectedType != BudgetType.CATEGORY || selectedCategory != null) &&
(selectedType != BudgetType.MEMBER || selectedMemberId != null)
) {
Text("确定")
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("取消")
}
}
)
}

View File

@@ -1,38 +1,23 @@
package com.yovinchen.bookkeeping.ui.dialog
import android.util.Log
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilterChip
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import com.yovinchen.bookkeeping.model.Category
import com.yovinchen.bookkeeping.model.TransactionType
import com.yovinchen.bookkeeping.utils.IconManager
private const val TAG = "CategoryManagementDialog"
@@ -41,233 +26,217 @@ private const val TAG = "CategoryManagementDialog"
fun CategoryManagementDialog(
onDismiss: () -> Unit,
categories: List<Category>,
onAddCategory: (String, TransactionType) -> Unit,
onAddCategory: (String, TransactionType, Int?) -> Unit,
onDeleteCategory: (Category) -> Unit,
onUpdateCategory: (Category, String) -> Unit,
onUpdateCategory: (Category, String, Int?) -> Unit,
selectedType: TransactionType,
onTypeChange: (TransactionType) -> Unit
) {
var newCategoryName by remember { mutableStateOf("") }
var showDialog by remember { mutableStateOf(true) }
var showDeleteDialog by remember { mutableStateOf(false) }
var showEditDialog by remember { mutableStateOf(false) }
var selectedCategory: Category? by remember { mutableStateOf(null) }
var editingCategoryName by remember { mutableStateOf("") }
val filteredCategories = categories.filter { it.type == selectedType }
var showAddDialog by remember { mutableStateOf(false) }
var editingCategory by remember { mutableStateOf<Category?>(null) }
Log.d(TAG, "Dialog state - showDialog: $showDialog, showDeleteDialog: $showDeleteDialog")
Log.d(TAG, "Selected category: ${selectedCategory?.name}")
if (showDialog) {
AlertDialog(
onDismissRequest = {
Log.d(TAG, "Main dialog dismiss requested")
showDialog = false
onDismiss()
},
title = { Text("类别管理") },
text = {
Column(
AlertDialog(
onDismissRequest = onDismiss,
title = { Text("类别管理") },
text = {
Column {
// 类型选择器
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.padding(bottom = 8.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
// 类型选择
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
TransactionType.values().forEach { type ->
FilterChip(
selected = selectedType == TransactionType.EXPENSE,
onClick = {
Log.d(TAG, "Switching to EXPENSE type")
onTypeChange(TransactionType.EXPENSE)
},
label = { Text("支出") }
)
FilterChip(
selected = selectedType == TransactionType.INCOME,
onClick = {
Log.d(TAG, "Switching to INCOME type")
onTypeChange(TransactionType.INCOME)
},
label = { Text("收入") }
)
}
Spacer(modifier = Modifier.height(16.dp))
// 添加新类别
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
OutlinedTextField(
value = newCategoryName,
onValueChange = { newCategoryName = it },
label = { Text("新类别名称") },
modifier = Modifier.weight(1f)
)
Spacer(modifier = Modifier.width(8.dp))
IconButton(
onClick = {
if (newCategoryName.isNotBlank()) {
Log.d(TAG, "Adding new category: $newCategoryName")
onAddCategory(newCategoryName, selectedType)
newCategoryName = ""
}
selected = type == selectedType,
onClick = { onTypeChange(type) },
label = {
Text(when (type) {
TransactionType.EXPENSE -> "支出"
TransactionType.INCOME -> "收入"
})
}
) {
Icon(Icons.Default.Add, contentDescription = "添加类别")
}
)
}
}
Spacer(modifier = Modifier.height(16.dp))
// 类别列表
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(filteredCategories) { category ->
// 类别列表
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.weight(1f)
) {
items(categories.filter { it.type == selectedType }) { category ->
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
.clickable { editingCategory = category },
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.weight(1f)
) {
Text(
text = category.name,
modifier = Modifier
.weight(1f)
.clickable {
selectedCategory = category
editingCategoryName = category.name
showEditDialog = true
}
)
IconButton(
onClick = {
Log.d(TAG, "Selected category for deletion: ${category.name}")
selectedCategory = category
showDeleteDialog = true
// 显示类别图标
if (category.icon != null) {
Icon(
imageVector = ImageVector.vectorResource(id = category.icon),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
} else {
IconManager.getCategoryIconVector(category.name)?.let { icon ->
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
}
) {
Icon(Icons.Default.Delete, contentDescription = "删除类别")
}
Spacer(modifier = Modifier.width(8.dp))
Text(category.name)
}
IconButton(
onClick = { onDeleteCategory(category) },
enabled = categories.size > 1
) {
Icon(
Icons.Default.Delete,
contentDescription = "删除",
tint = if (categories.size > 1)
MaterialTheme.colorScheme.error
else
MaterialTheme.colorScheme.onSurface.copy(alpha = 0.38f)
)
}
}
}
}
},
confirmButton = {
TextButton(
onClick = {
Log.d(TAG, "Main dialog confirmed")
showDialog = false
onDismiss()
}
// 添加类别按钮
Button(
onClick = { showAddDialog = true },
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
) {
Text("完成")
Icon(Icons.Default.Add, contentDescription = null)
Spacer(modifier = Modifier.width(8.dp))
Text("添加类别")
}
}
)
}
},
confirmButton = {
TextButton(onClick = onDismiss) {
Text("完成")
}
}
)
// 删除确认对话框
if (showDeleteDialog && selectedCategory != null) {
AlertDialog(
onDismissRequest = {
Log.d(TAG, "Delete dialog dismissed")
showDeleteDialog = false
selectedCategory = null
},
title = { Text("确认删除") },
text = {
Text(
text = buildString {
append("确定要删除类别 ")
append(selectedCategory?.name ?: "")
append(" 吗?")
}
)
},
confirmButton = {
TextButton(
onClick = {
try {
selectedCategory?.let { category ->
Log.d(TAG, "Confirming deletion of category: ${category.name}")
onDeleteCategory(category)
}
} catch (e: Exception) {
Log.e(TAG, "Error during category deletion callback", e)
e.printStackTrace()
} finally {
showDeleteDialog = false
selectedCategory = null
}
}
) {
Text("确定")
}
},
dismissButton = {
TextButton(
onClick = {
Log.d(TAG, "Canceling deletion")
showDeleteDialog = false
selectedCategory = null
}
) {
Text("取消")
}
// 添加类别对话框
if (showAddDialog) {
CategoryEditDialog(
onDismiss = { showAddDialog = false },
onConfirm = { name, iconResId ->
onAddCategory(name, selectedType, iconResId)
showAddDialog = false
}
)
}
// 编辑类别对话框
if (showEditDialog && selectedCategory != null) {
AlertDialog(
onDismissRequest = {
showEditDialog = false
selectedCategory = null
editingCategoryName = ""
editingCategory?.let { category ->
CategoryEditDialog(
onDismiss = { editingCategory = null },
onConfirm = { name, iconResId ->
onUpdateCategory(category, name, iconResId)
editingCategory = null
},
title = { Text("编辑类别") },
text = {
OutlinedTextField(
value = editingCategoryName,
onValueChange = { editingCategoryName = it },
label = { Text("类别名称") }
)
},
confirmButton = {
TextButton(
onClick = {
if (editingCategoryName.isNotBlank()) {
selectedCategory?.let { category ->
onUpdateCategory(category, editingCategoryName)
}
}
showEditDialog = false
selectedCategory = null
editingCategoryName = ""
}
) {
Text("确定")
}
},
dismissButton = {
TextButton(
onClick = {
showEditDialog = false
selectedCategory = null
editingCategoryName = ""
}
) {
Text("取消")
}
}
initialName = category.name,
initialIcon = category.icon
)
}
}
@Composable
private fun CategoryEditDialog(
onDismiss: () -> Unit,
onConfirm: (String, Int?) -> Unit,
initialName: String = "",
initialIcon: Int? = null
) {
var name by remember { mutableStateOf(initialName) }
var selectedIcon by remember { mutableStateOf(initialIcon) }
var showIconPicker by remember { mutableStateOf(false) }
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(if (initialName.isEmpty()) "添加类别" else "编辑类别") },
text = {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("名称") },
modifier = Modifier.fillMaxWidth()
)
// 图标选择按钮
Button(
onClick = { showIconPicker = true },
modifier = Modifier.fillMaxWidth()
) {
selectedIcon?.let { iconResId ->
Icon(
imageVector = ImageVector.vectorResource(id = iconResId),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
Spacer(modifier = Modifier.width(8.dp))
}
Text(if (selectedIcon == null) "选择图标" else "更改图标")
}
}
},
confirmButton = {
TextButton(
onClick = {
if (name.isNotBlank()) {
onConfirm(name, selectedIcon)
}
}
) {
Text("确定")
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("取消")
}
}
)
if (showIconPicker) {
IconPickerDialog(
onDismiss = { showIconPicker = false },
onIconSelected = {
selectedIcon = it
showIconPicker = false
},
selectedIcon = selectedIcon,
isMemberIcon = false,
title = "选择类别图标"
)
}
}

View File

@@ -0,0 +1,61 @@
package com.yovinchen.bookkeeping.ui.dialog
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import com.yovinchen.bookkeeping.utils.IconManager
@Composable
fun IconPickerDialog(
onDismiss: () -> Unit,
onIconSelected: (Int) -> Unit,
selectedIcon: Int? = null,
isMemberIcon: Boolean = false,
title: String = "选择图标"
) {
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(title) },
text = {
LazyVerticalGrid(
columns = GridCells.Fixed(4),
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
val icons = if (isMemberIcon) {
IconManager.getAllMemberIcons()
} else {
IconManager.getAllCategoryIcons()
}
items(icons) { iconResId ->
Icon(
imageVector = ImageVector.vectorResource(id = iconResId),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clickable { onIconSelected(iconResId) },
tint = if (selectedIcon == iconResId) MaterialTheme.colorScheme.primary else Color.Unspecified
)
}
}
},
confirmButton = {
TextButton(onClick = onDismiss) {
Text("取消")
}
}
)
}

View File

@@ -7,20 +7,25 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import com.yovinchen.bookkeeping.model.Member
import com.yovinchen.bookkeeping.utils.IconManager
@Composable
fun MemberManagementDialog(
onDismiss: () -> Unit,
members: List<Member>,
onAddMember: (String, String) -> Unit,
onAddMember: (String, String, Int?) -> Unit,
onDeleteMember: (Member) -> Unit,
onUpdateMember: (Member, String, String) -> Unit
onUpdateMember: (Member, String, String, Int?) -> Unit
) {
var showAddDialog by remember { mutableStateOf(false) }
var selectedMember by remember { mutableStateOf<Member?>(null) }
@@ -43,41 +48,65 @@ fun MemberManagementDialog(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = member.name,
style = MaterialTheme.typography.titleMedium
)
if (member.description.isNotEmpty()) {
Text(
text = member.description,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.weight(1f)
) {
// 显示成员图标
if (member.icon != null) {
Icon(
imageVector = ImageVector.vectorResource(member.icon),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
} else {
IconManager.getMemberIconVector(member.name)?.let { icon ->
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
}
}
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(
text = member.name,
style = MaterialTheme.typography.titleMedium
)
if (member.description.isNotEmpty()) {
Text(
text = member.description,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
Row {
IconButton(onClick = { selectedMember = member }) {
Icon(Icons.Default.Edit, "编辑成员")
Icon(Icons.Default.Edit, contentDescription = "编辑")
}
IconButton(onClick = { onDeleteMember(member) }) {
Icon(Icons.Default.Delete, "删除成员")
Icon(Icons.Default.Delete, contentDescription = "删除")
}
}
}
if (members.indexOf(member) < members.size - 1) {
HorizontalDivider()
}
}
}
Button(
onClick = { showAddDialog = true },
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp)
.padding(top = 8.dp)
) {
Icon(Icons.Default.Add, "添加成员")
Icon(Icons.Default.Add, contentDescription = null)
Spacer(modifier = Modifier.width(8.dp))
Text("添加成员")
}
@@ -85,32 +114,31 @@ fun MemberManagementDialog(
},
confirmButton = {
TextButton(onClick = onDismiss) {
Text("关闭")
Text("完成")
}
}
)
// 添加成员对话框
if (showAddDialog) {
MemberEditDialog(
onDismiss = { showAddDialog = false },
onConfirm = { name, description ->
onAddMember(name, description)
onConfirm = { name, description, iconResId ->
onAddMember(name, description, iconResId)
showAddDialog = false
}
)
}
// 编辑成员对话框
selectedMember?.let { member ->
MemberEditDialog(
onDismiss = { selectedMember = null },
onConfirm = { name, description ->
onUpdateMember(member, name, description)
onConfirm = { name, description, iconResId ->
onUpdateMember(member, name, description, iconResId)
selectedMember = null
},
initialName = member.name,
initialDescription = member.description
initialDescription = member.description,
initialIcon = member.icon
)
}
}
@@ -118,45 +146,63 @@ fun MemberManagementDialog(
@Composable
private fun MemberEditDialog(
onDismiss: () -> Unit,
onConfirm: (String, String) -> Unit,
onConfirm: (String, String, Int?) -> Unit,
initialName: String = "",
initialDescription: String = ""
initialDescription: String = "",
initialIcon: Int? = null
) {
var name by remember { mutableStateOf(initialName) }
var description by remember { mutableStateOf(initialDescription) }
var selectedIcon by remember { mutableStateOf(initialIcon) }
var showIconPicker by remember { mutableStateOf(false) }
AlertDialog(
onDismissRequest = onDismiss,
title = { Text(if (initialName.isEmpty()) "添加成员" else "编辑成员") },
text = {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
OutlinedTextField(
value = name,
onValueChange = { name = it },
label = { Text("成员名称") },
label = { Text("名称") },
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = description,
onValueChange = { description = it },
label = { Text("描述(可选)") },
label = { Text("描述") },
modifier = Modifier.fillMaxWidth()
)
// 图标选择按钮
Button(
onClick = { showIconPicker = true },
modifier = Modifier.fillMaxWidth()
) {
selectedIcon?.let { iconResId ->
Icon(
imageVector = ImageVector.vectorResource(iconResId),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
Spacer(modifier = Modifier.width(8.dp))
}
Text(if (selectedIcon == null) "选择图标" else "更改图标")
}
}
},
confirmButton = {
TextButton(
onClick = {
if (name.isNotBlank()) {
onConfirm(name.trim(), description.trim())
onConfirm(name, description, selectedIcon)
}
},
enabled = name.isNotBlank()
}
) {
Text("确定")
}
@@ -167,4 +213,17 @@ private fun MemberEditDialog(
}
}
)
if (showIconPicker) {
IconPickerDialog(
onDismiss = { showIconPicker = false },
onIconSelected = {
selectedIcon = it
showIconPicker = false
},
selectedIcon = selectedIcon,
isMemberIcon = true,
title = "选择成员图标"
)
}
}

View File

@@ -1,20 +1,13 @@
package com.yovinchen.bookkeeping.ui.navigation
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.List
import androidx.compose.material.icons.filled.Analytics
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
@@ -22,20 +15,42 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import com.yovinchen.bookkeeping.R
import com.yovinchen.bookkeeping.model.AnalysisType
import com.yovinchen.bookkeeping.model.ThemeMode
import com.yovinchen.bookkeeping.ui.screen.*
import androidx.compose.material3.*
import androidx.compose.ui.unit.dp
import java.time.YearMonth
import java.time.format.DateTimeFormatter
sealed class Screen(
val route: String,
val title: String,
val icon: ImageVector? = null
val iconResId: Int? = null
) {
object Home : Screen("home", "记账", Icons.AutoMirrored.Filled.List)
object Analysis : Screen("analysis", "分析", Icons.Default.Analytics)
object Settings : Screen("settings", "设置", Icons.Default.Settings)
@Composable
fun icon(): ImageVector? = iconResId?.let { ImageVector.vectorResource(it) }
object Home : Screen(
"home",
"记账",
iconResId = R.drawable.account
)
object Analysis : Screen(
"analysis",
"分析",
iconResId = R.drawable.piechart
)
object Settings : Screen(
"settings",
"设置",
iconResId = R.drawable.setting
)
object Budget : Screen(
"budget",
"预算管理"
)
object CategoryDetail : Screen(
"category_detail/{category}/{startMonth}/{endMonth}",
"分类详情"
@@ -75,18 +90,33 @@ fun MainNavigation(
onThemeChange: (ThemeMode) -> Unit
) {
val navController = rememberNavController()
val items = listOf(
Screen.Home,
Screen.Analysis,
Screen.Settings
)
Scaffold(
bottomBar = {
NavigationBar {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
Screen.bottomNavigationItems().forEach { screen ->
items.forEach { screen ->
val selected = currentRoute == screen.route
NavigationBarItem(
icon = { Icon(screen.icon!!, contentDescription = screen.title) },
icon = {
screen.icon()?.let { icon ->
Icon(
imageVector = icon,
contentDescription = screen.title,
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
}
},
label = { Text(screen.title) },
selected = currentRoute == screen.route,
selected = selected,
onClick = {
navController.navigate(screen.route) {
popUpTo(navController.graph.findStartDestination().id) {
@@ -122,9 +152,16 @@ fun MainNavigation(
composable(Screen.Settings.route) {
SettingsScreen(
currentTheme = currentTheme,
onThemeChange = onThemeChange
onThemeChange = onThemeChange,
onNavigateToBudget = {
navController.navigate(Screen.Budget.route)
}
)
}
composable(Screen.Budget.route) {
BudgetScreen()
}
composable(
route = Screen.CategoryDetail.route,

View File

@@ -38,12 +38,14 @@ import com.yovinchen.bookkeeping.model.MemberStat
import com.yovinchen.bookkeeping.ui.components.CategoryPieChart
import com.yovinchen.bookkeeping.ui.components.CategoryStatItem
import com.yovinchen.bookkeeping.ui.components.DateRangePicker
import com.yovinchen.bookkeeping.ui.components.DetailedAnalysisReport
import com.yovinchen.bookkeeping.ui.components.MonthlyYearlyReport
import com.yovinchen.bookkeeping.ui.components.TrendLineChart
import com.yovinchen.bookkeeping.viewmodel.AnalysisViewModel
import java.time.YearMonth
enum class ViewMode {
CATEGORY, MEMBER
CATEGORY, MEMBER, REPORT
}
@OptIn(ExperimentalMaterial3Api::class)
@@ -93,7 +95,13 @@ fun AnalysisScreen(
Button(
onClick = { showViewModeMenu = true }
) {
Text(if (currentViewMode == ViewMode.CATEGORY) "分类" else "成员")
Text(
when {
currentViewMode == ViewMode.CATEGORY -> "分类"
currentViewMode == ViewMode.MEMBER -> "成员"
else -> "报表"
}
)
Icon(Icons.Default.ArrowDropDown, "切换视图")
}
DropdownMenu(
@@ -114,6 +122,13 @@ fun AnalysisScreen(
showViewModeMenu = false
}
)
DropdownMenuItem(
text = { Text("报表") },
onClick = {
currentViewMode = ViewMode.REPORT
showViewModeMenu = false
}
)
}
}
@@ -159,41 +174,68 @@ fun AnalysisScreen(
}
}
else -> {
// 饼图视图
item {
CategoryPieChart(
categoryData = categoryStats.map { Pair(it.category, it.percentage.toFloat()) },
memberData = memberStats.map { Pair(it.member, it.percentage.toFloat()) },
currentViewMode = currentViewMode == ViewMode.MEMBER,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.padding(bottom = 16.dp),
onCategoryClick = { category ->
if (currentViewMode == ViewMode.CATEGORY) {
onNavigateToCategoryDetail(category, startMonth, endMonth)
} else {
onNavigateToMemberDetail(category, startMonth, endMonth, selectedAnalysisType)
if (currentViewMode == ViewMode.REPORT) {
// 报表视图
item {
MonthlyYearlyReport(
records = records,
period = if (startMonth == endMonth) "月度" else "年度",
startMonth = startMonth,
endMonth = endMonth,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
}
// 详细分析报表
item {
DetailedAnalysisReport(
records = records,
startMonth = startMonth,
endMonth = endMonth,
modifier = Modifier
.fillMaxWidth()
.padding(top = 16.dp)
)
}
} else {
// 饼图视图
item {
CategoryPieChart(
categoryData = categoryStats.map { Pair(it.category, it.percentage.toFloat()) },
memberData = memberStats.map { Pair(it.member, it.percentage.toFloat()) },
currentViewMode = currentViewMode == ViewMode.MEMBER,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.padding(bottom = 16.dp),
onCategoryClick = { category ->
if (currentViewMode == ViewMode.CATEGORY) {
onNavigateToCategoryDetail(category, startMonth, endMonth)
} else {
onNavigateToMemberDetail(category, startMonth, endMonth, selectedAnalysisType)
}
}
}
)
}
)
}
// 统计列表
items(if (currentViewMode == ViewMode.CATEGORY) categoryStats else memberStats) { stat ->
val category = if (stat is CategoryStat) stat.category else null
val member = if (stat is MemberStat) stat.member else null
// 统计列表
items(if (currentViewMode == ViewMode.CATEGORY) categoryStats else memberStats) { stat ->
val category = if (stat is CategoryStat) stat.category else null
val member = if (stat is MemberStat) stat.member else null
CategoryStatItem(
stat = stat,
onClick = {
if (currentViewMode == ViewMode.CATEGORY && category != null) {
onNavigateToCategoryDetail(category, startMonth, endMonth)
} else if (currentViewMode == ViewMode.MEMBER && member != null) {
onNavigateToMemberDetail(member, startMonth, endMonth, selectedAnalysisType)
CategoryStatItem(
stat = stat,
onClick = {
if (currentViewMode == ViewMode.CATEGORY && category != null) {
onNavigateToCategoryDetail(category, startMonth, endMonth)
} else if (currentViewMode == ViewMode.MEMBER && member != null) {
onNavigateToMemberDetail(member, startMonth, endMonth, selectedAnalysisType)
}
}
}
)
)
}
}
}
}

View File

@@ -0,0 +1,411 @@
package com.yovinchen.bookkeeping.ui.screen
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.yovinchen.bookkeeping.model.*
import com.yovinchen.bookkeeping.ui.dialog.BudgetEditDialog
import com.yovinchen.bookkeeping.viewmodel.BudgetViewModel
import com.yovinchen.bookkeeping.viewmodel.HomeViewModel
import com.yovinchen.bookkeeping.viewmodel.MemberViewModel
import java.text.NumberFormat
import java.util.Locale
/**
* 预算管理界面
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun BudgetScreen(
viewModel: BudgetViewModel = viewModel(),
homeViewModel: HomeViewModel = viewModel(),
memberViewModel: MemberViewModel = viewModel()
) {
val budgetStatuses by viewModel.activeBudgetStatuses.collectAsState()
val totalBudgetStatus by viewModel.totalBudgetStatus.collectAsState()
val categoryBudgetStatuses by viewModel.categoryBudgetStatuses.collectAsState()
val memberBudgetStatuses by viewModel.memberBudgetStatuses.collectAsState()
val showBudgetDialog by viewModel.showBudgetDialog.collectAsState()
val editingBudget by viewModel.editingBudget.collectAsState()
val categories by homeViewModel.categories.collectAsState()
val members by memberViewModel.allMembers.collectAsState(initial = emptyList())
var selectedTab by remember { mutableStateOf(0) }
val tabs = listOf("总览", "分类预算", "成员预算")
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
// 页面标题
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "预算管理",
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold
)
// 添加预算按钮
IconButton(
onClick = { viewModel.showEditBudgetDialog() }
) {
Icon(
imageVector = Icons.Default.Add,
contentDescription = "添加预算",
tint = MaterialTheme.colorScheme.primary
)
}
}
Spacer(modifier = Modifier.height(16.dp))
// 总预算概览卡片
totalBudgetStatus?.let { status ->
BudgetOverviewCard(status)
Spacer(modifier = Modifier.height(16.dp))
}
// Tab 选择器
TabRow(selectedTabIndex = selectedTab) {
tabs.forEachIndexed { index, title ->
Tab(
selected = selectedTab == index,
onClick = { selectedTab = index },
text = { Text(title) }
)
}
}
Spacer(modifier = Modifier.height(16.dp))
// Tab 内容
when (selectedTab) {
0 -> BudgetOverviewTab(budgetStatuses, viewModel)
1 -> CategoryBudgetTab(categoryBudgetStatuses, viewModel)
2 -> MemberBudgetTab(memberBudgetStatuses, viewModel)
}
}
// 预算编辑对话框
if (showBudgetDialog) {
BudgetEditDialog(
budget = editingBudget,
categories = categories.filter { it.type == TransactionType.EXPENSE },
members = members,
onDismiss = { viewModel.hideBudgetDialog() },
onConfirm = { budget ->
if (editingBudget == null) {
viewModel.createBudget(
type = budget.type,
amount = budget.amount,
categoryName = budget.categoryName,
memberId = budget.memberId,
alertThreshold = budget.alertThreshold
)
} else {
viewModel.updateBudget(budget)
}
viewModel.hideBudgetDialog()
}
)
}
}
/**
* 预算概览卡片
*/
@Composable
private fun BudgetOverviewCard(budgetStatus: BudgetStatus) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "本月总预算",
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
Text(
text = formatCurrency(budgetStatus.budget.amount),
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)
}
Spacer(modifier = Modifier.height(12.dp))
// 进度条
LinearProgressIndicator(
progress = budgetStatus.percentage.toFloat().coerceIn(0f, 1f),
modifier = Modifier
.fillMaxWidth()
.height(8.dp)
.clip(RoundedCornerShape(4.dp)),
color = when {
budgetStatus.isOverBudget -> MaterialTheme.colorScheme.error
budgetStatus.isNearLimit -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.primary
}
)
Spacer(modifier = Modifier.height(8.dp))
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Column {
Text(
text = "已使用",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = formatCurrency(budgetStatus.spent),
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Medium
)
}
Column(horizontalAlignment = Alignment.End) {
Text(
text = "剩余",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Text(
text = formatCurrency(budgetStatus.remaining),
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Medium,
color = when {
budgetStatus.isOverBudget -> MaterialTheme.colorScheme.error
budgetStatus.isNearLimit -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.primary
}
)
}
}
if (budgetStatus.isOverBudget) {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "⚠️ 已超出预算 ${formatCurrency(kotlin.math.abs(budgetStatus.remaining))}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center
)
} else if (budgetStatus.isNearLimit) {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "⚠️ 接近预算限制",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.tertiary,
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Center
)
}
}
}
}
/**
* 预算总览标签页
*/
@Composable
private fun BudgetOverviewTab(
budgetStatuses: List<BudgetStatus>,
viewModel: BudgetViewModel
) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(budgetStatuses) { status ->
BudgetItem(
budgetStatus = status,
onClick = { viewModel.showEditBudgetDialog(status.budget) },
onToggleEnabled = { viewModel.toggleBudgetEnabled(status.budget) }
)
}
}
}
/**
* 分类预算标签页
*/
@Composable
private fun CategoryBudgetTab(
categoryBudgetStatuses: List<BudgetStatus>,
viewModel: BudgetViewModel
) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(categoryBudgetStatuses) { status ->
BudgetItem(
budgetStatus = status,
onClick = { viewModel.showEditBudgetDialog(status.budget) },
onToggleEnabled = { viewModel.toggleBudgetEnabled(status.budget) }
)
}
}
}
/**
* 成员预算标签页
*/
@Composable
private fun MemberBudgetTab(
memberBudgetStatuses: List<BudgetStatus>,
viewModel: BudgetViewModel
) {
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(memberBudgetStatuses) { status ->
BudgetItem(
budgetStatus = status,
onClick = { viewModel.showEditBudgetDialog(status.budget) },
onToggleEnabled = { viewModel.toggleBudgetEnabled(status.budget) }
)
}
}
}
/**
* 预算项目组件
*/
@Composable
private fun BudgetItem(
budgetStatus: BudgetStatus,
onClick: () -> Unit,
onToggleEnabled: () -> Unit
) {
Card(
modifier = Modifier
.fillMaxWidth()
.clickable { onClick() },
colors = CardDefaults.cardColors(
containerColor = if (budgetStatus.budget.isEnabled) {
MaterialTheme.colorScheme.surface
} else {
MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.5f)
}
)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column(
modifier = Modifier.weight(1f)
) {
Text(
text = when (budgetStatus.budget.type) {
BudgetType.TOTAL -> "总预算"
BudgetType.CATEGORY -> budgetStatus.budget.categoryName ?: "未知分类"
BudgetType.MEMBER -> "成员预算"
},
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Medium
)
Spacer(modifier = Modifier.height(4.dp))
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = "预算: ${formatCurrency(budgetStatus.budget.amount)}",
style = MaterialTheme.typography.bodyMedium
)
Text(
text = "已用: ${formatCurrency(budgetStatus.spent)}",
style = MaterialTheme.typography.bodyMedium,
color = when {
budgetStatus.isOverBudget -> MaterialTheme.colorScheme.error
budgetStatus.isNearLimit -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.onSurfaceVariant
}
)
}
Spacer(modifier = Modifier.height(8.dp))
LinearProgressIndicator(
progress = budgetStatus.percentage.toFloat().coerceIn(0f, 1f),
modifier = Modifier
.fillMaxWidth()
.height(4.dp)
.clip(RoundedCornerShape(2.dp)),
color = when {
budgetStatus.isOverBudget -> MaterialTheme.colorScheme.error
budgetStatus.isNearLimit -> MaterialTheme.colorScheme.tertiary
else -> MaterialTheme.colorScheme.primary
}
)
}
IconButton(onClick = onToggleEnabled) {
Icon(
imageVector = if (budgetStatus.budget.isEnabled) {
Icons.Default.CheckCircle
} else {
Icons.Default.Cancel
},
contentDescription = if (budgetStatus.budget.isEnabled) "禁用" else "启用",
tint = if (budgetStatus.budget.isEnabled) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.onSurfaceVariant
}
)
}
}
}
}
/**
* 格式化货币
*/
private fun formatCurrency(amount: Double): String {
val format = NumberFormat.getCurrencyInstance(Locale.CHINA)
return format.format(amount)
}

View File

@@ -20,7 +20,6 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@@ -54,7 +53,6 @@ fun HomeScreen(
val filteredRecords by viewModel.filteredRecords.collectAsState()
val categories by viewModel.categories.collectAsState(initial = emptyList())
val members by viewModel.members.collectAsState(initial = emptyList())
val selectedMember by viewModel.selectedMember.collectAsState()
val totalIncome by viewModel.totalIncome.collectAsState()
val totalExpense by viewModel.totalExpense.collectAsState()

View File

@@ -144,7 +144,7 @@ fun MemberDetailScreen(
categoryData = categoryData,
memberData = emptyList(),
currentViewMode = false,
onCategoryClick = { selectedCategory ->
onCategoryClick = {
// 暂时不处理点击事件
}
)

View File

@@ -1,52 +1,54 @@
package com.yovinchen.bookkeeping.ui.screen
import android.content.Context
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Divider
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.yovinchen.bookkeeping.model.Settings
import com.yovinchen.bookkeeping.model.ThemeMode
import com.yovinchen.bookkeeping.ui.components.ColorPicker
import com.yovinchen.bookkeeping.ui.components.predefinedColors
import com.yovinchen.bookkeeping.ui.dialog.CategoryManagementDialog
import com.yovinchen.bookkeeping.ui.dialog.MemberManagementDialog
import com.yovinchen.bookkeeping.viewmodel.MemberViewModel
import com.yovinchen.bookkeeping.viewmodel.SettingsViewModel
import com.yovinchen.bookkeeping.ui.components.*
import com.yovinchen.bookkeeping.ui.dialog.*
import com.yovinchen.bookkeeping.utils.FilePickerUtil
import com.yovinchen.bookkeeping.viewmodel.*
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(
currentTheme: ThemeMode,
onThemeChange: (ThemeMode) -> Unit,
onNavigateToBudget: () -> Unit = {},
viewModel: SettingsViewModel = viewModel(),
memberViewModel: MemberViewModel = viewModel()
) {
var showThemeDialog by remember { mutableStateOf(false) }
var showCategoryDialog by remember { mutableStateOf(false) }
var showMemberDialog by remember { mutableStateOf(false) }
var showBackupDialog by remember { mutableStateOf(false) }
var showRestoreDialog by remember { mutableStateOf(false) }
val categories by viewModel.categories.collectAsState()
val selectedType by viewModel.selectedCategoryType.collectAsState()
val members by memberViewModel.allMembers.collectAsState(initial = emptyList())
val monthStartDay by viewModel.monthStartDay.collectAsState()
val settings by viewModel.settings.collectAsState()
val context = LocalContext.current
var showMonthStartDayDialog by remember { mutableStateOf(false) }
Column(modifier = Modifier.fillMaxSize()) {
// 成员管理设置项
@@ -56,7 +58,7 @@ fun SettingsScreen(
modifier = Modifier.clickable { showMemberDialog = true }
)
Divider()
HorizontalDivider()
// 类别管理设置项
ListItem(
@@ -65,7 +67,27 @@ fun SettingsScreen(
modifier = Modifier.clickable { showCategoryDialog = true }
)
Divider()
HorizontalDivider()
// 数据备份设置项
ListItem(
headlineContent = { Text("数据备份") },
supportingContent = { Text("备份和恢复数据") },
modifier = Modifier.clickable { showBackupDialog = true }
)
HorizontalDivider()
// 预算管理设置项
ListItem(
headlineContent = { Text("预算管理") },
supportingContent = { Text("设置和管理预算") },
modifier = Modifier.clickable {
onNavigateToBudget()
}
)
HorizontalDivider()
// 主题设置项
ListItem(
@@ -82,6 +104,15 @@ fun SettingsScreen(
},
modifier = Modifier.clickable { showThemeDialog = true }
)
HorizontalDivider()
// 月度开始日期设置项
ListItem(
headlineContent = { Text("月度开始日期") },
supportingContent = { Text("每月从${monthStartDay}号开始计算") },
modifier = Modifier.clickable { showMonthStartDayDialog = true }
)
if (showThemeDialog) {
AlertDialog(
@@ -117,7 +148,7 @@ fun SettingsScreen(
}
)
Divider(modifier = Modifier.padding(vertical = 8.dp))
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
// 颜色选择器
Text(
@@ -145,32 +176,230 @@ fun SettingsScreen(
}
)
}
}
// 月度开始日期对话框
if (showMonthStartDayDialog) {
AlertDialog(
onDismissRequest = { showMonthStartDayDialog = false },
title = { Text("选择月度开始日期") },
text = {
Column {
Text("选择每月记账的开始日期1-28号")
Spacer(modifier = Modifier.height(16.dp))
// 日期选择器
val days = (1..28).toList()
LazyVerticalGrid(
columns = GridCells.Fixed(7),
modifier = Modifier.fillMaxWidth().height(280.dp),
contentPadding = PaddingValues(4.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
items(days) { day ->
Surface(
onClick = {
viewModel.setMonthStartDay(day)
showMonthStartDayDialog = false
},
shape = RoundedCornerShape(8.dp),
color = if (day == monthStartDay) {
MaterialTheme.colorScheme.primaryContainer
} else {
MaterialTheme.colorScheme.surface
},
border = BorderStroke(
width = 1.dp,
color = if (day == monthStartDay) {
MaterialTheme.colorScheme.primary
} else {
MaterialTheme.colorScheme.outline
}
),
modifier = Modifier
.fillMaxWidth()
.aspectRatio(1f)
) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxSize()
) {
Text(
text = day.toString(),
style = MaterialTheme.typography.bodyMedium,
color = if (day == monthStartDay) {
MaterialTheme.colorScheme.onPrimaryContainer
} else {
MaterialTheme.colorScheme.onSurface
}
)
}
}
}
}
}
},
confirmButton = {
TextButton(onClick = { showMonthStartDayDialog = false }) {
Text("取消")
}
}
)
}
// 类别管理对话框
if (showCategoryDialog) {
CategoryManagementDialog(
onDismiss = { showCategoryDialog = false },
categories = categories,
onAddCategory = viewModel::addCategory,
onDeleteCategory = viewModel::deleteCategory,
onUpdateCategory = viewModel::updateCategory,
selectedType = selectedType,
onTypeChange = viewModel::setSelectedCategoryType
)
}
// 备份对话框
if (showBackupDialog) {
AlertDialog(
onDismissRequest = { showBackupDialog = false },
title = { Text("数据备份") },
text = {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Button(
onClick = { viewModel.exportToCSV(context) },
modifier = Modifier.fillMaxWidth()
) {
Text("导出为CSV")
}
Button(
onClick = { viewModel.exportToExcel(context) },
modifier = Modifier.fillMaxWidth()
) {
Text("导出为Excel")
}
Button(
onClick = { showRestoreDialog = true },
modifier = Modifier.fillMaxWidth()
) {
Text("恢复数据")
}
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Text("自动备份", modifier = Modifier.weight(1f))
Switch(
checked = viewModel.isAutoBackupEnabled.collectAsState().value,
onCheckedChange = { viewModel.setAutoBackup(it) }
)
}
if (viewModel.isAutoBackupEnabled.collectAsState().value) {
Text(
"自动备份将每24小时创建一次备份保存在应用私有目录中",
style = MaterialTheme.typography.bodySmall
)
}
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
// 备份加密开关
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Text("备份加密", modifier = Modifier.weight(1f))
Switch(
checked = settings?.encryptBackup ?: true,
onCheckedChange = { enabled ->
viewModel.updateSettings(
settings?.copy(encryptBackup = enabled) ?: Settings(encryptBackup = enabled)
)
}
)
}
Text(
"开启后,导出的备份文件将被加密保护",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
},
confirmButton = {
TextButton(onClick = { showBackupDialog = false }) {
Text("关闭")
}
}
)
}
// 成员管理对话框
if (showMemberDialog) {
MemberManagementDialog(
onDismiss = { showMemberDialog = false },
members = members,
onAddMember = memberViewModel::addMember,
onDeleteMember = memberViewModel::deleteMember,
onUpdateMember = { member, name, description ->
memberViewModel.updateMember(member.copy(name = name, description = description))
}
)
// 恢复对话框
if (showRestoreDialog) {
AlertDialog(
onDismissRequest = { showRestoreDialog = false },
title = { Text("恢复数据") },
text = {
Column {
Text("请选择要恢复的备份文件CSV或Excel格式")
Text(
"注意:恢复数据将覆盖当前的所有数据!",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error
)
}
},
confirmButton = {
TextButton(
onClick = {
showRestoreDialog = false
// 启动文件选择器
val activity = context as? ComponentActivity
if (activity != null) {
FilePickerUtil.startFilePicker(activity) { file ->
viewModel.restoreData(context, file)
}
} else {
Toast.makeText(context, "无法启动文件选择器", Toast.LENGTH_SHORT).show()
}
}
) {
Text("选择文件")
}
},
dismissButton = {
TextButton(onClick = { showRestoreDialog = false }) {
Text("取消")
}
}
)
}
// 类别管理对话框
if (showCategoryDialog) {
CategoryManagementDialog(
onDismiss = { showCategoryDialog = false },
categories = categories,
onAddCategory = { name, type, iconResId ->
viewModel.addCategory(name, type, iconResId)
},
onDeleteCategory = viewModel::deleteCategory,
onUpdateCategory = { category, newName, iconResId ->
viewModel.updateCategory(category, newName, iconResId)
},
selectedType = selectedType,
onTypeChange = viewModel::setSelectedCategoryType
)
}
// 成员管理对话框
if (showMemberDialog) {
MemberManagementDialog(
onDismiss = { showMemberDialog = false },
members = members,
onAddMember = { name, description, iconResId ->
memberViewModel.addMember(name, description, iconResId)
},
onDeleteMember = memberViewModel::deleteMember,
onUpdateMember = { member, name, description, iconResId ->
memberViewModel.updateMember(member.copy(
name = name,
description = description,
icon = iconResId
))
}
)
}
}
}

View File

@@ -0,0 +1,85 @@
package com.yovinchen.bookkeeping.utils
import java.time.LocalDate
import java.time.YearMonth
import java.time.ZoneId
import java.util.Date
object DateUtils {
/**
* 根据月度开始日期计算给定日期所属的记账月份
* @param date 要判断的日期
* @param monthStartDay 月度开始日期1-28
* @return 该日期所属的记账月份
*/
fun getAccountingMonth(date: Date, monthStartDay: Int): YearMonth {
val localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
return getAccountingMonth(localDate, monthStartDay)
}
/**
* 根据月度开始日期计算给定日期所属的记账月份
* @param date 要判断的日期
* @param monthStartDay 月度开始日期1-28
* @return 该日期所属的记账月份
*/
fun getAccountingMonth(date: LocalDate, monthStartDay: Int): YearMonth {
val dayOfMonth = date.dayOfMonth
return if (dayOfMonth >= monthStartDay) {
// 当前日期大于等于开始日期,属于当前月
YearMonth.from(date)
} else {
// 当前日期小于开始日期,属于上个月
YearMonth.from(date.minusMonths(1))
}
}
/**
* 获取记账月份的开始日期
* @param yearMonth 记账月份
* @param monthStartDay 月度开始日期1-28
* @return 该记账月份的开始日期
*/
fun getMonthStartDate(yearMonth: YearMonth, monthStartDay: Int): LocalDate {
return yearMonth.atDay(monthStartDay)
}
/**
* 获取记账月份的结束日期
* @param yearMonth 记账月份
* @param monthStartDay 月度开始日期1-28
* @return 该记账月份的结束日期
*/
fun getMonthEndDate(yearMonth: YearMonth, monthStartDay: Int): LocalDate {
val nextMonth = yearMonth.plusMonths(1)
return nextMonth.atDay(monthStartDay).minusDays(1)
}
/**
* 检查日期是否在指定的记账月份内
* @param date 要检查的日期
* @param yearMonth 记账月份
* @param monthStartDay 月度开始日期1-28
* @return 是否在该记账月份内
*/
fun isInAccountingMonth(date: Date, yearMonth: YearMonth, monthStartDay: Int): Boolean {
val localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
return isInAccountingMonth(localDate, yearMonth, monthStartDay)
}
/**
* 检查日期是否在指定的记账月份内
* @param date 要检查的日期
* @param yearMonth 记账月份
* @param monthStartDay 月度开始日期1-28
* @return 是否在该记账月份内
*/
fun isInAccountingMonth(date: LocalDate, yearMonth: YearMonth, monthStartDay: Int): Boolean {
val startDate = getMonthStartDate(yearMonth, monthStartDay)
val endDate = getMonthEndDate(yearMonth, monthStartDay)
return date >= startDate && date <= endDate
}
}

View File

@@ -0,0 +1,136 @@
package com.yovinchen.bookkeeping.utils
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import android.util.Base64
import java.security.KeyStore
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.GCMParameterSpec
/**
* 加密工具类,使用 Android Keystore 系统安全地存储加密密钥
*/
object EncryptionUtils {
private const val ANDROID_KEYSTORE = "AndroidKeyStore"
private const val TRANSFORMATION = "AES/GCM/NoPadding"
private const val KEY_ALIAS = "BookkeepingBackupKey"
private const val GCM_TAG_LENGTH = 128
init {
generateKey()
}
/**
* 生成或获取加密密钥
*/
private fun generateKey() {
val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE)
keyStore.load(null)
// 如果密钥已存在,则不需要重新生成
if (keyStore.containsAlias(KEY_ALIAS)) {
return
}
val keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEYSTORE)
val keyGenParameterSpec = KeyGenParameterSpec.Builder(
KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setRandomizedEncryptionRequired(true)
.build()
keyGenerator.init(keyGenParameterSpec)
keyGenerator.generateKey()
}
/**
* 获取密钥
*/
private fun getKey(): SecretKey {
val keyStore = KeyStore.getInstance(ANDROID_KEYSTORE)
keyStore.load(null)
return keyStore.getKey(KEY_ALIAS, null) as SecretKey
}
/**
* 加密字符串
* @param plainText 要加密的明文
* @return Base64编码的加密数据包含IV
*/
fun encrypt(plainText: String): String {
val cipher = Cipher.getInstance(TRANSFORMATION)
cipher.init(Cipher.ENCRYPT_MODE, getKey())
val iv = cipher.iv
val encryptedBytes = cipher.doFinal(plainText.toByteArray(Charsets.UTF_8))
// 将IV和加密数据组合
val combined = ByteArray(iv.size + encryptedBytes.size)
System.arraycopy(iv, 0, combined, 0, iv.size)
System.arraycopy(encryptedBytes, 0, combined, iv.size, encryptedBytes.size)
return Base64.encodeToString(combined, Base64.DEFAULT)
}
/**
* 解密字符串
* @param encryptedData Base64编码的加密数据
* @return 解密后的明文
*/
fun decrypt(encryptedData: String): String {
val combined = Base64.decode(encryptedData, Base64.DEFAULT)
// 提取IV前12字节
val iv = combined.sliceArray(0..11)
val encryptedBytes = combined.sliceArray(12 until combined.size)
val cipher = Cipher.getInstance(TRANSFORMATION)
val spec = GCMParameterSpec(GCM_TAG_LENGTH, iv)
cipher.init(Cipher.DECRYPT_MODE, getKey(), spec)
val decryptedBytes = cipher.doFinal(encryptedBytes)
return String(decryptedBytes, Charsets.UTF_8)
}
/**
* 加密字节数组
* @param data 要加密的数据
* @return 加密后的数据包含IV
*/
fun encryptBytes(data: ByteArray): ByteArray {
val cipher = Cipher.getInstance(TRANSFORMATION)
cipher.init(Cipher.ENCRYPT_MODE, getKey())
val iv = cipher.iv
val encryptedBytes = cipher.doFinal(data)
// 将IV和加密数据组合
val combined = ByteArray(iv.size + encryptedBytes.size)
System.arraycopy(iv, 0, combined, 0, iv.size)
System.arraycopy(encryptedBytes, 0, combined, iv.size, encryptedBytes.size)
return combined
}
/**
* 解密字节数组
* @param encryptedData 加密的数据
* @return 解密后的数据
*/
fun decryptBytes(encryptedData: ByteArray): ByteArray {
// 提取IV前12字节
val iv = encryptedData.sliceArray(0..11)
val encryptedBytes = encryptedData.sliceArray(12 until encryptedData.size)
val cipher = Cipher.getInstance(TRANSFORMATION)
val spec = GCMParameterSpec(GCM_TAG_LENGTH, iv)
cipher.init(Cipher.DECRYPT_MODE, getKey(), spec)
return cipher.doFinal(encryptedBytes)
}
}

View File

@@ -0,0 +1,167 @@
package com.yovinchen.bookkeeping.utils
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.result.contract.ActivityResultContracts
import com.yovinchen.bookkeeping.getPreregisteredFilePickerLauncher
import java.io.File
import java.io.FileOutputStream
/**
* 文件选择器工具类
* 用于处理文件选择、权限获取和文件处理的工具类
*
* 主要功能:
* 1. 启动系统文件选择器
* 2. 处理选择结果
* 3. 将选择的文件复制到应用缓存目录
* 4. 文件类型验证
*/
object FilePickerUtil {
/**
* 当前活跃的文件选择回调
* 用于在文件选择完成后调用
*/
private var currentCallback: ((File) -> Unit)? = null
/**
* 启动文件选择器
*
* @param activity 当前活动,用于启动文件选择器
* @param onFileSelected 文件选择完成后的回调函数,参数为选中的文件
*/
fun startFilePicker(activity: ComponentActivity, onFileSelected: (File) -> Unit) {
currentCallback = onFileSelected
try {
// 设置可选择的文件类型限制为CSV和Excel文件
val mimeTypes = arrayOf(
"text/csv",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-excel"
)
// 使用预注册的文件选择器启动文件选择流程
activity.getPreregisteredFilePickerLauncher().launch(mimeTypes)
} catch (e: Exception) {
// 文件选择器启动失败时显示错误提示
Toast.makeText(activity, "无法启动文件选择器:${e.message}", Toast.LENGTH_SHORT).show()
currentCallback = null
}
}
/**
* 处理文件选择结果
*
* @param context 上下文对象用于访问ContentResolver
* @param uri 选中文件的URI如果用户取消选择则为null
*/
fun handleFileSelection(context: Context, uri: Uri?) {
if (uri == null) {
// 用户未选择文件时显示提示
Toast.makeText(context, "未选择文件", Toast.LENGTH_SHORT).show()
currentCallback = null
return
}
try {
// 获取文件MIME类型
val mimeType = context.contentResolver.getType(uri)
// 验证文件类型是否合法
if (!isValidFileType(uri.toString(), mimeType)) {
Toast.makeText(context, "请选择CSV或Excel文件", Toast.LENGTH_SHORT).show()
return
}
// 获取持久性权限,确保应用在重启后仍能访问该文件
val takeFlags: Int = Intent.FLAG_GRANT_READ_URI_PERMISSION or
Intent.FLAG_GRANT_WRITE_URI_PERMISSION
context.contentResolver.takePersistableUriPermission(uri, takeFlags)
// 将选中的文件复制到应用私有目录
val tempFile = copyUriToTempFile(context, uri)
if (tempFile != null) {
// 调用回调函数,传递临时文件
currentCallback?.invoke(tempFile)
} else {
Toast.makeText(context, "文件处理失败,请重试", Toast.LENGTH_SHORT).show()
}
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(context, "文件处理出错:${e.message}", Toast.LENGTH_SHORT).show()
} finally {
// 清除回调引用,避免内存泄漏
currentCallback = null
}
}
/**
* 验证文件类型是否合法
*
* @param fileName 文件名,用于检查文件扩展名
* @param mimeType 文件MIME类型
* @return 如果文件类型合法则返回true否则返回false
*/
private fun isValidFileType(fileName: String, mimeType: String?): Boolean {
val fileExtension = fileName.lowercase()
return fileExtension.endsWith(".csv") ||
fileExtension.endsWith(".csv.enc") ||
fileExtension.endsWith(".xlsx") ||
fileExtension.endsWith(".xlsx.enc") ||
fileExtension.endsWith(".xls") ||
fileExtension.endsWith(".xls.enc") ||
fileExtension.endsWith(".enc") ||
mimeType == "text/csv" ||
mimeType == "application/vnd.ms-excel" ||
mimeType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" ||
mimeType == "application/octet-stream" // 加密文件可能被识别为二进制流
}
/**
* 将URI指向的文件复制到应用缓存目录
*
* @param context 上下文对象用于访问ContentResolver和缓存目录
* @param uri 要复制的文件URI
* @return 复制后的临时文件如果复制失败则返回null
*/
private fun copyUriToTempFile(context: Context, uri: Uri): File? {
return try {
// 获取文件名,如果无法获取则使用时间戳作为文件名
val fileName = getFileName(context, uri) ?: "temp_backup_${System.currentTimeMillis()}"
val tempFile = File(context.cacheDir, fileName)
// 从URI读取内容并写入临时文件
context.contentResolver.openInputStream(uri)?.use { inputStream ->
FileOutputStream(tempFile).use { outputStream ->
inputStream.copyTo(outputStream)
}
}
tempFile
} catch (e: Exception) {
e.printStackTrace()
null
}
}
/**
* 从URI中获取文件名
*
* @param context 上下文对象用于访问ContentResolver
* @param uri 文件URI
* @return 文件名如果无法获取则返回null
*/
private fun getFileName(context: Context, uri: Uri): String? {
var fileName: String? = null
context.contentResolver.query(uri, null, null, null, null)?.use { cursor ->
if (cursor.moveToFirst()) {
val displayNameIndex = cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME)
if (displayNameIndex != -1) {
fileName = cursor.getString(displayNameIndex)
}
}
}
return fileName
}
}

View File

@@ -0,0 +1,132 @@
package com.yovinchen.bookkeeping.utils
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.vectorResource
import com.yovinchen.bookkeeping.R
/**
* 图标管理器
* 集中管理应用中使用的各类图标资源
*
* 主要功能:
* 1. 管理分类图标和成员图标的映射关系
* 2. 提供根据名称获取对应图标的方法
* 3. 提供获取所有可用图标的方法
*/
object IconManager {
/**
* 类别图标映射
* 将分类名称映射到对应的图标资源ID
*/
private val categoryIcons = mapOf(
"餐饮" to R.drawable.ic_category_food_24dp, // 餐饮类别对应食物图标
"交通" to R.drawable.ic_category_taxi_24dp, // 交通类别对应出租车图标
"购物" to R.drawable.ic_category_supermarket_24dp, // 购物类别对应超市图标
"娱乐" to R.drawable.ic_category_bar_24dp, // 娱乐类别对应酒吧图标
"居住" to R.drawable.ic_category_hotel_24dp, // 居住类别对应酒店图标
"医疗" to R.drawable.ic_category_medicine_24dp, // 医疗类别对应药品图标
"教育" to R.drawable.ic_category_training_24dp, // 教育类别对应培训图标
"宠物" to R.drawable.ic_category_pet_24dp, // 宠物类别对应宠物图标
"鲜花" to R.drawable.ic_category_flower_24dp, // 鲜花类别对应花图标
"外卖" to R.drawable.ic_category_delivery_24dp, // 外卖类别对应外卖图标
"数码" to R.drawable.ic_category_digital_24dp, // 数码类别对应数码产品图标
"化妆品" to R.drawable.ic_category_cosmetics_24dp, // 化妆品类别对应化妆品图标
"水果" to R.drawable.ic_category_fruit_24dp, // 水果类别对应水果图标
"零食" to R.drawable.ic_category_snack_24dp, // 零食类别对应零食图标
"蔬菜" to R.drawable.ic_category_vegetable_24dp, // 蔬菜类别对应蔬菜图标
"工资" to R.drawable.ic_category_membership_24dp, // 工资类别对应会员图标
"礼物" to R.drawable.ic_category_gift_24dp, // 礼物类别对应礼物图标
"其他" to R.drawable.ic_category_more_24dp, // 其他类别对应更多图标
"会员" to R.drawable.ic_category_membership_24dp, // 会员类别对应会员图标
"奖金" to R.drawable.ic_category_gift_24dp, // 奖金类别对应礼物图标
"投资" to R.drawable.ic_category_digital_24dp // 投资类别对应数码图标
)
/**
* 成员图标映射
* 将成员角色名称映射到对应的图标资源ID
*/
private val memberIcons = mapOf(
"自己" to R.drawable.ic_member_boy_24dp, // 自己对应男孩图标
"老婆" to R.drawable.ic_member_bride_24dp, // 老婆对应新娘图标
"老公" to R.drawable.ic_member_groom_24dp, // 老公对应新郎图标
"家庭" to R.drawable.ic_member_family_24dp, // 家庭对应家庭图标
"儿子" to R.drawable.ic_member_baby_boy_24dp, // 儿子对应男婴图标
"女儿" to R.drawable.ic_member_baby_girl_24dp, // 女儿对应女婴图标
"爸爸" to R.drawable.ic_member_father_24dp, // 爸爸对应父亲图标
"妈妈" to R.drawable.ic_member_mother_24dp, // 妈妈对应母亲图标
"爷爷" to R.drawable.ic_member_grandfather_24dp, // 爷爷对应祖父图标
"奶奶" to R.drawable.ic_member_grandmother_24dp, // 奶奶对应祖母图标
"男生" to R.drawable.ic_member_boy_24dp, // 男生对应男孩图标
"女生" to R.drawable.ic_member_girl_24dp, // 女生对应女孩图标
"外公" to R.drawable.ic_member_grandfather_24dp, // 外公对应祖父图标
"外婆" to R.drawable.ic_member_grandmother_24dp, // 外婆对应祖母图标
"其他" to R.drawable.ic_member_girl_24dp // 其他成员使用女孩图标作为默认值
)
/**
* 获取分类对应的图标向量
* 用于在Compose UI中直接使用
*
* @param name 分类名称
* @return 对应的图标向量如果未找到则返回null
*/
@Composable
fun getCategoryIconVector(name: String): ImageVector? {
return categoryIcons[name]?.let { ImageVector.vectorResource(id = it) }
}
/**
* 获取成员对应的图标向量
* 用于在Compose UI中直接使用
*
* @param name 成员名称
* @return 对应的图标向量如果未找到则返回null
*/
@Composable
fun getMemberIconVector(name: String): ImageVector? {
return memberIcons[name]?.let { ImageVector.vectorResource(id = it) }
}
/**
* 获取分类对应的图标资源ID
*
* @param name 分类名称
* @return 对应的图标资源ID如果未找到则返回null
*/
@DrawableRes
fun getCategoryIcon(name: String): Int? {
return categoryIcons[name]
}
/**
* 获取成员对应的图标资源ID
*
* @param name 成员名称
* @return 对应的图标资源ID如果未找到则返回null
*/
@DrawableRes
fun getMemberIcon(name: String): Int? {
return memberIcons[name]
}
/**
* 获取所有可用的分类图标资源ID列表
*
* @return 所有分类图标的资源ID列表
*/
fun getAllCategoryIcons(): List<Int> {
return categoryIcons.values.toList()
}
/**
* 获取所有可用的成员图标资源ID列表
*
* @return 所有成员图标的资源ID列表
*/
fun getAllMemberIcons(): List<Int> {
return memberIcons.values.toList()
}
}

View File

@@ -4,21 +4,22 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.yovinchen.bookkeeping.data.BookkeepingDatabase
import com.yovinchen.bookkeeping.data.SettingsRepository
import com.yovinchen.bookkeeping.model.AnalysisType
import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.CategoryStat
import com.yovinchen.bookkeeping.model.MemberStat
import com.yovinchen.bookkeeping.model.TransactionType
import com.yovinchen.bookkeeping.utils.DateUtils
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.time.LocalDateTime
import java.time.YearMonth
import java.time.ZoneId
import java.util.*
class AnalysisViewModel(application: Application) : AndroidViewModel(application) {
private val recordDao = BookkeepingDatabase.getDatabase(application).bookkeepingDao()
private val memberDao = BookkeepingDatabase.getDatabase(application).memberDao()
private val settingsRepository = SettingsRepository(BookkeepingDatabase.getDatabase(application).settingsDao())
private val _startMonth = MutableStateFlow(YearMonth.now())
val startMonth: StateFlow<YearMonth> = _startMonth.asStateFlow()
@@ -38,16 +39,41 @@ class AnalysisViewModel(application: Application) : AndroidViewModel(application
private val _records = MutableStateFlow<List<BookkeepingRecord>>(emptyList())
val records: StateFlow<List<BookkeepingRecord>> = _records.asStateFlow()
// 存储月度开始日期设置
private val _monthStartDay = MutableStateFlow(1)
val monthStartDay: StateFlow<Int> = _monthStartDay.asStateFlow()
init {
// 订阅设置变化,获取月度开始日期
viewModelScope.launch {
combine(startMonth, endMonth, selectedAnalysisType) { start, end, type ->
Triple(start, end, type)
}.collect { (start, end, type) ->
updateStats(start, end, type)
settingsRepository.getSettings().collect { settings ->
_monthStartDay.value = settings?.monthStartDay ?: 1
}
}
// 当月度开始日期、起始月份、结束月份或分析类型变化时,更新统计数据
viewModelScope.launch {
combine(
startMonth,
endMonth,
selectedAnalysisType,
monthStartDay
) { start, end, type, startDay ->
UpdateParams(start, end, type, startDay)
}.collect { params ->
updateStats(params.start, params.end, params.type, params.startDay)
}
}
}
// 用于传递更新参数的数据类
private data class UpdateParams(
val start: YearMonth,
val end: YearMonth,
val type: AnalysisType,
val startDay: Int
)
fun setStartMonth(month: YearMonth) {
_startMonth.value = month
}
@@ -60,16 +86,16 @@ class AnalysisViewModel(application: Application) : AndroidViewModel(application
_selectedAnalysisType.value = type
}
private suspend fun updateStats(startMonth: YearMonth, endMonth: YearMonth, type: AnalysisType) {
private suspend fun updateStats(startMonth: YearMonth, endMonth: YearMonth, type: AnalysisType, monthStartDay: Int) {
val records = recordDao.getAllRecords().first()
// 过滤日期范围内的记录
val monthRecords = records.filter {
val recordDate = Date(it.date.time)
val localDateTime = LocalDateTime.ofInstant(recordDate.toInstant(), ZoneId.systemDefault())
val yearMonth = YearMonth.from(localDateTime)
yearMonth.isAfter(startMonth.minusMonths(1)) &&
yearMonth.isBefore(endMonth.plusMonths(1))
// 使用 DateUtils 过滤日期范围内的记录
val monthRecords = records.filter { record ->
val recordDate = Date(record.date.time)
val accountingMonth = DateUtils.getAccountingMonth(recordDate, monthStartDay)
// 检查记账月份是否在选定的范围内
accountingMonth >= startMonth && accountingMonth <= endMonth
}
// 更新记录数据

View File

@@ -0,0 +1,185 @@
package com.yovinchen.bookkeeping.viewmodel
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.yovinchen.bookkeeping.data.BookkeepingDatabase
import com.yovinchen.bookkeeping.data.BudgetRepository
import com.yovinchen.bookkeeping.model.*
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import java.util.*
import java.util.Calendar
/**
* 预算管理 ViewModel
* 负责预算相关的业务逻辑和状态管理
*/
class BudgetViewModel(application: Application) : AndroidViewModel(application) {
private val database = BookkeepingDatabase.getDatabase(application)
private val budgetRepository = BudgetRepository(
database.budgetDao(),
database.bookkeepingDao(),
database.memberDao()
)
// 所有预算列表
val allBudgets = budgetRepository.getAllBudgets()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
// 当前活跃的预算状态
val activeBudgetStatuses = budgetRepository.getActiveBudgetStatuses()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
// 总预算状态
private val _totalBudgetStatus = MutableStateFlow<BudgetStatus?>(null)
val totalBudgetStatus: StateFlow<BudgetStatus?> = _totalBudgetStatus.asStateFlow()
// 分类预算状态
val categoryBudgetStatuses = budgetRepository.getCategoryBudgetStatuses()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
// 成员预算状态
val memberBudgetStatuses = budgetRepository.getMemberBudgetStatuses()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
// 编辑中的预算
private val _editingBudget = MutableStateFlow<Budget?>(null)
val editingBudget: StateFlow<Budget?> = _editingBudget.asStateFlow()
// 对话框显示状态
private val _showBudgetDialog = MutableStateFlow(false)
val showBudgetDialog: StateFlow<Boolean> = _showBudgetDialog.asStateFlow()
init {
// 初始化时加载总预算状态
loadTotalBudgetStatus()
}
/**
* 加载总预算状态
*/
private fun loadTotalBudgetStatus() {
viewModelScope.launch {
_totalBudgetStatus.value = budgetRepository.getTotalBudgetStatus()
}
}
/**
* 创建新预算
*/
fun createBudget(
type: BudgetType,
amount: Double,
categoryName: String? = null,
memberId: Int? = null,
alertThreshold: Double = 0.8
) {
viewModelScope.launch {
val calendar = Calendar.getInstance()
val startDate = calendar.time
// 设置结束日期为当月最后一天
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH))
calendar.set(Calendar.HOUR_OF_DAY, 23)
calendar.set(Calendar.MINUTE, 59)
calendar.set(Calendar.SECOND, 59)
val endDate = calendar.time
val budget = Budget(
type = type,
amount = amount,
categoryName = categoryName,
memberId = memberId,
startDate = startDate,
endDate = endDate,
alertThreshold = alertThreshold
)
budgetRepository.createBudget(budget)
loadTotalBudgetStatus()
}
}
/**
* 更新预算
*/
fun updateBudget(budget: Budget) {
viewModelScope.launch {
budgetRepository.updateBudget(budget)
loadTotalBudgetStatus()
}
}
/**
* 删除预算
*/
fun deleteBudget(budget: Budget) {
viewModelScope.launch {
budgetRepository.deleteBudget(budget)
loadTotalBudgetStatus()
}
}
/**
* 切换预算启用状态
*/
fun toggleBudgetEnabled(budget: Budget) {
viewModelScope.launch {
budgetRepository.updateBudgetEnabled(budget.id, !budget.isEnabled)
loadTotalBudgetStatus()
}
}
/**
* 显示预算编辑对话框
*/
fun showEditBudgetDialog(budget: Budget? = null) {
_editingBudget.value = budget
_showBudgetDialog.value = true
}
/**
* 隐藏预算编辑对话框
*/
fun hideBudgetDialog() {
_showBudgetDialog.value = false
_editingBudget.value = null
}
/**
* 检查预算警报
*/
fun checkBudgetAlerts() {
viewModelScope.launch {
val alerts = budgetRepository.checkBudgetAlerts()
// 这里可以触发通知或其他警报机制
// 暂时先不实现,等完成通知功能后再补充
}
}
/**
* 清理过期预算
*/
fun cleanupExpiredBudgets() {
viewModelScope.launch {
budgetRepository.cleanupExpiredBudgets()
}
}
}

View File

@@ -1,14 +1,15 @@
package com.yovinchen.bookkeeping.viewmodel
import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.yovinchen.bookkeeping.data.BookkeepingDatabase
import com.yovinchen.bookkeeping.data.SettingsRepository
import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.Category
import com.yovinchen.bookkeeping.model.Member
import com.yovinchen.bookkeeping.model.TransactionType
import com.yovinchen.bookkeeping.utils.DateUtils
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
@@ -19,10 +20,26 @@ import java.util.*
@OptIn(ExperimentalCoroutinesApi::class)
class HomeViewModel(application: Application) : AndroidViewModel(application) {
private val TAG = "HomeViewModel"
private val bookkeepingDao = BookkeepingDatabase.getDatabase(application).bookkeepingDao()
private val memberDao = BookkeepingDatabase.getDatabase(application).memberDao()
private val categoryDao = BookkeepingDatabase.getDatabase(application).categoryDao()
private val database = BookkeepingDatabase.getDatabase(application)
private val bookkeepingDao = database.bookkeepingDao()
private val memberDao = database.memberDao()
private val categoryDao = database.categoryDao()
private val settingsRepository = SettingsRepository(database.settingsDao())
// 设置相关
private val _monthStartDay = MutableStateFlow(1)
val monthStartDay: StateFlow<Int> = _monthStartDay.asStateFlow()
init {
viewModelScope.launch {
settingsRepository.ensureSettingsExist()
settingsRepository.getSettings().collect { settings ->
settings?.let {
_monthStartDay.value = it.monthStartDay
}
}
}
}
private val _selectedRecordType = MutableStateFlow<TransactionType?>(null)
val selectedRecordType: StateFlow<TransactionType?> = _selectedRecordType.asStateFlow()
@@ -58,17 +75,13 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
allRecords,
_selectedRecordType,
_selectedMonth,
_selectedMember
) { records, selectedType, selectedMonth, selectedMember ->
_selectedMember,
_monthStartDay
) { records, selectedType, selectedMonth, selectedMember, monthStartDay ->
records
.filter { record ->
val recordDate = record.date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate()
val recordYearMonth = YearMonth.from(recordDate)
val typeMatches = selectedType?.let { record.type == it } ?: true
val monthMatches = recordYearMonth == selectedMonth
val monthMatches = DateUtils.isInAccountingMonth(record.date, selectedMonth, monthStartDay)
val memberMatches = selectedMember?.let { record.memberId == it.id } ?: true
monthMatches && memberMatches && typeMatches
@@ -92,16 +105,12 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
val totalIncome = combine(
allRecords,
_selectedMonth,
_selectedMember
) { records, selectedMonth, selectedMember ->
_selectedMember,
_monthStartDay
) { records, selectedMonth, selectedMember, monthStartDay ->
records
.filter { record ->
val recordDate = record.date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate()
val recordYearMonth = YearMonth.from(recordDate)
val monthMatches = recordYearMonth == selectedMonth
val monthMatches = DateUtils.isInAccountingMonth(record.date, selectedMonth, monthStartDay)
val memberMatches = selectedMember?.let { record.memberId == it.id } ?: true
val typeMatches = record.type == TransactionType.INCOME
@@ -117,16 +126,12 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
val totalExpense = combine(
allRecords,
_selectedMonth,
_selectedMember
) { records, selectedMonth, selectedMember ->
_selectedMember,
_monthStartDay
) { records, selectedMonth, selectedMember, monthStartDay ->
records
.filter { record ->
val recordDate = record.date.toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDate()
val recordYearMonth = YearMonth.from(recordDate)
val monthMatches = recordYearMonth == selectedMonth
val monthMatches = DateUtils.isInAccountingMonth(record.date, selectedMonth, monthStartDay)
val memberMatches = selectedMember?.let { record.memberId == it.id } ?: true
val typeMatches = record.type == TransactionType.EXPENSE

View File

@@ -13,9 +13,9 @@ class MemberViewModel(application: Application) : AndroidViewModel(application)
val allMembers: Flow<List<Member>> = memberDao.getAllMembers()
fun addMember(name: String, description: String = "") {
fun addMember(name: String, description: String = "", iconResId: Int? = null) {
viewModelScope.launch {
val member = Member(name = name, description = description)
val member = Member(name = name, description = description, icon = iconResId)
memberDao.insertMember(member)
}
}

View File

@@ -1,28 +1,84 @@
package com.yovinchen.bookkeeping.viewmodel
import android.app.Application
import android.content.Context
import android.os.Environment
import android.widget.Toast
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.opencsv.CSVReader
import com.opencsv.CSVWriter
import com.yovinchen.bookkeeping.data.BookkeepingDatabase
import com.yovinchen.bookkeeping.data.SettingsRepository
import com.yovinchen.bookkeeping.model.BookkeepingRecord
import com.yovinchen.bookkeeping.model.Category
import com.yovinchen.bookkeeping.model.Settings
import com.yovinchen.bookkeeping.model.TransactionType
import com.yovinchen.bookkeeping.utils.EncryptionUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import java.io.File
import java.io.FileReader
import java.io.FileWriter
import java.io.StringWriter
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.concurrent.TimeUnit
@OptIn(ExperimentalCoroutinesApi::class)
class SettingsViewModel(application: Application) : AndroidViewModel(application) {
private val database = BookkeepingDatabase.getDatabase(application)
private val dao = database.bookkeepingDao()
private val memberDao = database.memberDao()
private val settingsRepository = SettingsRepository(database.settingsDao())
// 设置相关的状态
val settings: StateFlow<Settings?> = settingsRepository.getSettings()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = null
)
private val _isAutoBackupEnabled = MutableStateFlow(false)
val isAutoBackupEnabled: StateFlow<Boolean> = _isAutoBackupEnabled.asStateFlow()
private val _monthStartDay = MutableStateFlow(1)
val monthStartDay: StateFlow<Int> = _monthStartDay.asStateFlow()
init {
viewModelScope.launch {
// 确保设置存在
settingsRepository.ensureSettingsExist()
// 监听设置变化
settings.collect { settings ->
settings?.let {
_isAutoBackupEnabled.value = it.autoBackupEnabled
_monthStartDay.value = it.monthStartDay
}
}
}
}
private val _selectedCategoryType = MutableStateFlow(TransactionType.EXPENSE)
val selectedCategoryType: StateFlow<TransactionType> = _selectedCategoryType.asStateFlow()
val categories: StateFlow<List<Category>> = _selectedCategoryType
.flatMapLatest { type ->
val categories: StateFlow<List<Category>> = _selectedCategoryType.flatMapLatest { type ->
dao.getCategoriesByType(type)
}
.stateIn(
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
@@ -32,9 +88,9 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
_selectedCategoryType.value = type
}
fun addCategory(name: String, type: TransactionType) {
fun addCategory(name: String, type: TransactionType, iconResId: Int?) {
viewModelScope.launch {
val category = Category(name = name, type = type)
val category = Category(name = name, type = type, icon = iconResId)
dao.insertCategory(category)
}
}
@@ -45,9 +101,9 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
}
}
fun updateCategory(category: Category, newName: String) {
fun updateCategory(category: Category, newName: String, iconResId: Int?) {
viewModelScope.launch {
val updatedCategory = category.copy(name = newName)
val updatedCategory = category.copy(name = newName, icon = iconResId)
dao.updateCategory(updatedCategory)
// 更新所有使用该类别的记录
dao.updateRecordCategories(category.name, newName)
@@ -57,4 +113,313 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
suspend fun isCategoryInUse(categoryName: String): Boolean {
return dao.isCategoryInUse(categoryName)
}
fun setAutoBackup(enabled: Boolean) {
viewModelScope.launch {
_isAutoBackupEnabled.value = enabled
settingsRepository.updateAutoBackupEnabled(enabled)
if (enabled) {
schedulePeriodicBackup()
}
}
}
fun setMonthStartDay(day: Int) {
viewModelScope.launch {
_monthStartDay.value = day
settingsRepository.updateMonthStartDay(day)
}
}
private fun schedulePeriodicBackup() {
viewModelScope.launch(Dispatchers.IO) {
while (isAutoBackupEnabled.value) {
try {
// 创建自动备份
SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val backupDir = File(
getApplication<Application>().getExternalFilesDir(null), "auto_backups"
)
if (!backupDir.exists()) {
backupDir.mkdirs()
}
// 导出CSV
exportToCSV(getApplication(), backupDir)
// 等待24小时
delay(TimeUnit.HOURS.toMillis(24))
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}
fun exportToCSV(context: Context, customDir: File? = null) {
viewModelScope.launch(Dispatchers.IO) {
try {
val currentSettings = settings.value ?: Settings()
val timestamp =
SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val shouldEncrypt = currentSettings.encryptBackup
val fileName = if (shouldEncrypt) {
"bookkeeping_backup_$timestamp.csv.enc"
} else {
"bookkeeping_backup_$timestamp.csv"
}
val downloadsDir = customDir ?: Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS
)
val file = File(downloadsDir, fileName)
// 先创建CSV内容到字符串
val csvContent = StringWriter().use { stringWriter ->
val writer = CSVWriter(stringWriter)
// 写入头部
writer.writeNext(arrayOf("日期", "类型", "金额", "类别", "备注", "成员"))
// 获取所有记录和成员
val records = dao.getAllRecords().first()
val members = memberDao.getAllMembers().first()
// 写入数据行
records.forEach { record ->
val member = members.find { member -> member.id == record.memberId }
writer.writeNext(
arrayOf(
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(
record.date
),
record.type.toString(),
record.amount.toString(),
record.category,
record.description,
member?.name ?: "自己"
)
)
}
writer.close()
stringWriter.toString()
}
// 根据设置决定是否加密
if (shouldEncrypt) {
val encryptedContent = EncryptionUtils.encrypt(csvContent)
file.writeText(encryptedContent)
} else {
file.writeText(csvContent)
}
withContext(Dispatchers.Main) {
val message = if (shouldEncrypt) {
"CSV导出成功已加密: ${file.absolutePath}"
} else {
"CSV导出成功: ${file.absolutePath}"
}
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
} catch (e: Exception) {
e.printStackTrace()
withContext(Dispatchers.Main) {
Toast.makeText(context, "CSV导出失败: ${e.message}", Toast.LENGTH_LONG).show()
}
}
}
}
fun exportToExcel(context: Context) {
viewModelScope.launch(Dispatchers.IO) {
try {
val currentSettings = settings.value ?: Settings()
val shouldEncrypt = currentSettings.encryptBackup
val workbook = XSSFWorkbook()
val sheet = workbook.createSheet("账目记录")
// 创建标题行
val headerRow = sheet.createRow(0)
val headers = arrayOf("日期", "类型", "金额", "类别", "备注", "成员")
headers.forEachIndexed { index, header ->
headerRow.createCell(index).setCellValue(header)
}
// 获取所有记录和成员
val records = dao.getAllRecords().first()
val members = memberDao.getAllMembers().first()
records.forEachIndexed { index, record ->
val row = sheet.createRow(index + 1)
val member = members.find { member -> member.id == record.memberId }
row.createCell(0).setCellValue(
SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault()
).format(record.date)
)
row.createCell(1).setCellValue(record.type.toString())
row.createCell(2).setCellValue(record.amount)
row.createCell(3).setCellValue(record.category)
row.createCell(4).setCellValue(record.description)
row.createCell(5).setCellValue(member?.name ?: "自己")
}
val timestamp =
SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
val fileName = if (shouldEncrypt) {
"bookkeeping_backup_$timestamp.xlsx.enc"
} else {
"bookkeeping_backup_$timestamp.xlsx"
}
val downloadsDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
val file = File(downloadsDir, fileName)
if (shouldEncrypt) {
// 将 workbook 写入字节数组
val byteArrayOutputStream = java.io.ByteArrayOutputStream()
workbook.write(byteArrayOutputStream)
val excelBytes = byteArrayOutputStream.toByteArray()
// 加密字节数组
val encryptedBytes = EncryptionUtils.encryptBytes(excelBytes)
// 写入加密文件
file.writeBytes(encryptedBytes)
} else {
workbook.write(file.outputStream())
}
workbook.close()
withContext(Dispatchers.Main) {
val message = if (shouldEncrypt) {
"Excel导出成功已加密: ${file.absolutePath}"
} else {
"Excel导出成功: ${file.absolutePath}"
}
Toast.makeText(context, message, Toast.LENGTH_LONG).show()
}
} catch (e: Exception) {
e.printStackTrace()
withContext(Dispatchers.Main) {
Toast.makeText(context, "Excel导出失败: ${e.message}", Toast.LENGTH_LONG).show()
}
}
}
}
fun restoreData(context: Context, backupFile: File) {
viewModelScope.launch(Dispatchers.IO) {
try {
when {
backupFile.name.endsWith(".csv.enc", ignoreCase = true) -> {
// 解密CSV文件
val encryptedContent = backupFile.readText()
val decryptedContent = EncryptionUtils.decrypt(encryptedContent)
val tempFile = File(context.cacheDir, "temp_decrypted.csv")
tempFile.writeText(decryptedContent)
restoreFromCSV(tempFile)
tempFile.delete()
}
backupFile.name.endsWith(".csv", ignoreCase = true) -> {
restoreFromCSV(backupFile)
}
backupFile.name.endsWith(".xlsx.enc", ignoreCase = true) -> {
// 解密Excel文件
val encryptedBytes = backupFile.readBytes()
val decryptedBytes = EncryptionUtils.decryptBytes(encryptedBytes)
val tempFile = File(context.cacheDir, "temp_decrypted.xlsx")
tempFile.writeBytes(decryptedBytes)
restoreFromExcel(tempFile)
tempFile.delete()
}
backupFile.name.endsWith(".xlsx", ignoreCase = true) -> {
restoreFromExcel(backupFile)
}
else -> {
withContext(Dispatchers.Main) {
Toast.makeText(context, "不支持的文件格式", Toast.LENGTH_LONG).show()
}
return@launch
}
}
withContext(Dispatchers.Main) {
Toast.makeText(context, "数据恢复成功", Toast.LENGTH_LONG).show()
}
} catch (e: Exception) {
e.printStackTrace()
withContext(Dispatchers.Main) {
val errorMessage = when {
e.message?.contains("decrypt") == true -> "解密失败,请确认文件未损坏"
else -> "数据恢复失败: ${e.message}"
}
Toast.makeText(context, errorMessage, Toast.LENGTH_LONG).show()
}
}
}
}
private suspend fun restoreFromCSV(file: File) {
CSVReader(FileReader(file)).use { reader ->
// 跳过标题行
reader.readNext()
// 读取数据行
var currentLine = reader.readNext()
while (currentLine != null) {
val record = BookkeepingRecord(
type = TransactionType.valueOf(currentLine[1]),
amount = currentLine[2].toDouble(),
category = currentLine[3],
description = currentLine[4],
date = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).parse(
currentLine[0]
) ?: Date(),
memberId = findMemberIdByName(currentLine[5])
)
dao.insertRecord(record)
currentLine = reader.readNext()
}
}
}
private suspend fun restoreFromExcel(file: File) {
val workbook = XSSFWorkbook(file)
val sheet = workbook.getSheetAt(0)
// 跳过标题行
for (rowIndex in 1..sheet.lastRowNum) {
val row = sheet.getRow(rowIndex)
val record = BookkeepingRecord(
type = TransactionType.valueOf(row.getCell(1).stringCellValue),
amount = row.getCell(2).numericCellValue,
category = row.getCell(3).stringCellValue,
description = row.getCell(4).stringCellValue,
date = SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss",
Locale.getDefault()
).parse(row.getCell(0).stringCellValue),
memberId = findMemberIdByName(row.getCell(5).stringCellValue)
)
dao.insertRecord(record)
}
workbook.close()
}
private suspend fun findMemberIdByName(name: String): Int? {
return memberDao.getAllMembers().first().find { member -> member.name == name }?.id
}
fun updateSettings(settings: Settings) {
viewModelScope.launch {
settingsRepository.updateSettings(settings)
}
}
}

View File

@@ -0,0 +1,24 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M193.3,124.3h480.5A106.1,106.1 0,0 1,779.8 230.4v63.7H87V230.4a106.1,106.1 0,0 1,106.2 -106.1z"
android:fillColor="#FCB423"/>
<path
android:pathData="M157.8,160.9h512a70.6,70.6 0,0 1,70.6 70.6v99.3H87V231.5a70.6,70.6 0,0 1,70.8 -70.6z"
android:fillColor="#FFD62C"/>
<path
android:pathData="M87,240.3h743a107.5,107.5 0,0 1,107.5 107.5v420.7a134.5,134.5 0,0 1,-134.5 134.5H197.6A110.4,110.4 0,0 1,87 792.7V240.3z"
android:fillColor="#7518ED"/>
<path
android:pathData="M87,280.8h734.3A74.5,74.5 0,0 1,896 355.3v444.8a101.3,101.3 0,0 1,-101.3 101.3H197.6A110.4,110.4 0,0 1,87 791V280.8z"
android:fillColor="#9539FC"/>
<path
android:pathData="M760.1,504.4a112.9,112.9 0,0 0,0 225.9L896,730.3L896,504.4zM757.3,663.9a46.5,46.5 0,1 1,46.5 -46.5,46.5 46.5,0 0,1 -46.5,46.5z"
android:fillColor="#741AE8"/>
<path
android:pathData="M760.1,467.9a112.9,112.9 0,0 0,0 225.9L896,693.8L896,467.9zM757.3,627.4a46.5,46.5 0,1 1,46.5 -46.5,46.5 46.5,0 0,1 -46.5,46.5z"
android:fillColor="#FFFFFF"/>
</vector>

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.1 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733368452865" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2083" data-darkreader-inline-fill="" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M259.69 193.89h456.53c8.52 0 15.44 6.92 15.44 15.44v521.43H202.21v-479.4c0-31.72 25.75-57.47 57.47-57.47z" fill="#57B7F9" p-id="2084" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #0a5b92;"></path><path d="M259.69 665.92h471.97v125.74H259.69c-31.72 0-57.47-25.75-57.47-57.47V723.4c0-31.72 25.75-57.47 57.47-57.47z" fill="#33A1F2" p-id="2085" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #1067a6;"></path><path d="M267.14 701.58h453.9c0.67 0 1.21 0.54 1.21 1.21v52.1c0 0.67-0.54 1.21-1.21 1.21h-453.9c-15.04 0-27.26-12.21-27.26-27.26 0-15.04 12.21-27.26 27.26-27.26z" fill="#A1DCFF" p-id="2086" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #343839;"></path><path d="M262.27 193.66v472.26s-55.01 10.41-55.01 38.17V239.34s11.15-33.61 55.01-45.68z" fill="#33A1F2" p-id="2087" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #1067a6;"></path><path d="M515.07 801.66H265.09c-40.18 0-72.87-32.69-72.87-72.87s32.69-72.87 72.87-72.87h417.4c5.52 0 10 4.48 10 10s-4.48 10-10 10H265.08c-29.15 0-52.87 23.72-52.87 52.87s23.72 52.87 52.87 52.87h249.98c5.52 0 10 4.48 10 10s-4.48 10-10 10z" fill="#333333" p-id="2088" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #272a2b;"></path><path d="M202.21 741.89c-5.52 0-10-4.48-10-10V257.88c0-40.18 32.69-72.87 72.87-72.87h451.96c13.57 0 24.61 11.04 24.61 24.61v336.04c0 5.52-4.48 10-10 10s-10-4.48-10-10V209.63c0-2.54-2.07-4.61-4.61-4.61H265.08c-29.15 0-52.87 23.72-52.87 52.87V731.9c0 5.52-4.48 10-10 10z" fill="#333333" p-id="2089" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #272a2b;"></path><path d="M610.28 253.75h-58.59v154.39l58.59-28.83V253.75z" fill="#FFAC3B" p-id="2090" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #ffb148;"></path><path d="M610.28 253.75h58.6v154.39l-58.6-28.83V253.75z" fill="#FFD44A" p-id="2091" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #ffd753;"></path><path d="M789.78 646.03l-43.7-43.7L568.5 779.9l13.7 73.71 207.58-207.58z" fill="#FFAC3B" p-id="2092" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #a86205;"></path><path d="M789.78 646.03l43.7 43.7L655.9 867.31l-73.7-13.7 207.58-207.58z" fill="#FFD44A" p-id="2093" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #785c04;"></path><path d="M668.88 418.14c-1.51 0-3.02-0.34-4.41-1.03l-54.18-26.66-54.18 26.66a10.002 10.002 0 0 1-14.42-8.97V253.75c0-5.52 4.48-10 10-10h117.19c5.52 0 10 4.48 10 10v154.39a10 10 0 0 1-4.72 8.49c-1.61 1-3.45 1.51-5.28 1.51z m-58.59-48.83c1.51 0 3.02 0.34 4.42 1.03l44.18 21.74V263.75H561.7v128.33l44.18-21.74c1.39-0.69 2.9-1.03 4.42-1.03z" fill="#333333" p-id="2094" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #cbc5bc;"></path><path d="M813.81 573.291l48.7 48.698c10.677 10.678 10.684 28.023 0 38.708l-29.034 29.033-87.406-87.405 29.034-29.034c10.677-10.677 28.022-10.684 38.707 0z" fill="#F76C69" p-id="2095" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #f56d68;"></path><path d="M640.86 876.79c-0.51 0-1.02 0-1.54-0.03l-48.58-1.59c-16.35-0.54-29.58-13.76-30.11-30.11l-1.59-48.58c-0.43-13.08 4.63-25.89 13.88-35.14L765.4 568.86c13.44-13.44 35.31-13.44 48.75 0l52.79 52.79c13.44 13.44 13.44 35.31 0 48.75L674.46 862.88c-8.89 8.89-21.06 13.91-33.6 13.91z m148.91-298.03c-3.71 0-7.41 1.41-10.23 4.23L587.06 775.47a27.575 27.575 0 0 0-8.04 20.34l1.59 48.58c0.19 5.85 4.93 10.59 10.78 10.78l48.58 1.59c7.57 0.24 14.99-2.68 20.34-8.04l192.48-192.48c5.64-5.64 5.64-14.82 0-20.47L800 582.98a14.43 14.43 0 0 0-10.23-4.23z" fill="#333333" p-id="2096" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #272a2b;"></path><path d="M799.92 666.17c-2.56 0-5.12-0.98-7.07-2.93l-48.74-48.74c-3.91-3.91-3.91-10.24 0-14.14s10.24-3.91 14.14 0l48.74 48.74c3.91 3.91 3.91 10.24 0 14.14a9.973 9.973 0 0 1-7.07 2.93z" fill="#333333" p-id="2097" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #cbc5bc;"></path></svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1733368445240" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1583" data-darkreader-inline-fill="" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M788.15 816.26H255.01c-49.14 0-88.98-39.84-88.98-88.98V475.71c0-49.14 39.84-88.98 88.98-88.98h155.68c155.29 0 301.1 74.66 391.87 200.65l0.26 0.37a276.537 276.537 0 0 1 52.17 161.66c0 36.92-29.93 66.85-66.85 66.85z" fill="#57B7F9" p-id="1584" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #0a5b92;"></path><path d="M506.75 396.43s0 88.27 87.97 163.08c74.13 63.04 230.31 59.19 230.31 59.19S700.77 413.67 506.75 396.42z" fill="#D4EFFF" p-id="1585" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #252729;"></path><path d="M817.24 628.74h-0.06c-15.5-0.1-56.38-1.2-101.09-9.37-56.13-10.26-99.15-27.83-127.85-52.24-50.61-43.04-73-90.57-82.87-122.87-1.61-5.28 1.36-10.87 6.64-12.49 5.28-1.61 10.87 1.36 12.49 6.64 9.09 29.74 29.77 73.57 76.7 113.48 25.99 22.1 65.86 38.19 118.49 47.8 43.16 7.88 82.64 8.95 97.62 9.05 5.52 0.03 9.97 4.54 9.94 10.06-0.03 5.5-4.51 9.94-10 9.94z" fill="#333333" p-id="1586" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #272a2b;"></path><path d="M384.59 618.75H177.34V501.3h104.04c42.46 0 82.33 20.42 107.15 54.87l0.07 0.1a75.653 75.653 0 0 1 14.27 44.2c0 10.09-8.18 18.28-18.28 18.28z" fill="#D4EFFF" p-id="1587" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #252729;"></path><path d="M165.5 723.68h688.29s11.23 92.58-65.64 92.58H247.82s-82.32-20.45-82.32-92.58z" fill="#33A1F2" p-id="1588" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #1067a6;"></path><path d="M788.15 826.26H255.01c-54.58 0-98.98-44.4-98.98-98.98v-30.54c0-5.52 4.48-10 10-10s10 4.48 10 10v30.54c0 43.55 35.43 78.98 78.98 78.98h533.14c31.34 0 56.85-25.5 56.85-56.85 0-56.27-17.39-110.15-50.28-155.81l-0.26-0.37c-43.62-60.54-101.77-110.51-168.19-144.52-66.41-34.01-140.96-51.98-215.57-51.98H255.01c-43.55 0-78.98 35.43-78.98 78.98v142.76c0 5.52-4.48 10-10 10s-10-4.48-10-10V475.71c0-54.58 44.4-98.98 98.98-98.98h155.68c77.77 0 155.46 18.73 224.69 54.18s129.84 87.53 175.3 150.63l0.26 0.37C846.3 630.99 865 688.92 865 749.41c0 42.37-34.47 76.85-76.85 76.85z" fill="#333333" p-id="1589" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #272a2b;"></path><path d="M754.79 733.68H170.87c-5.52 0-10-4.48-10-10s4.48-10 10-10h583.92c5.52 0 10 4.48 10 10s-4.48 10-10 10z" fill="#333333" p-id="1590" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #272a2b;"></path><path d="M638.22 278.13l120.21-93.43c1.6-1.25 3.66-1.8 5.68-1.57 14.18 1.57 26.44 1.95 41.48 5.19 2.43 0.52 3.51 3.38 2 5.35L717.5 310.78l-79.28-32.64z" fill="#A1DCFF" p-id="1591" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #90d5fb;"></path><path d="M717.5 311.77l62 27.6c2.06 0.94 4.45 0.84 6.43-0.27l65.04-36.36a9.275 9.275 0 0 1 7.6-0.66l16.74 5.87a7.736 7.736 0 0 1 3.33 12.31l-52.47 61.75c-15.4 18.36-48.05 9.04-48.05 9.04s-251.8-69.94-251.83-69.95c-45.45-13.7-51.3-23.32-51.3-37.31 0-18.65 37.31-23.32 37.31-23.32 8.61-4.28 27.72-14.13 54.54-4.93l71.38 23.58 79.28 32.64z" fill="#FFF6DB" p-id="1592" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #362902;"></path><path d="M482 271.73L782 369s33.47 8 55.23 0c0 0-21.97 30.11-58.1 21.05l-281.54-79.28s-27.58-10.3-15.58-39.04z" fill="#33A1F2" p-id="1593" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #1067a6;"></path><path d="M797.61 402.42h-0.27c-11.34-0.04-20.57-2.64-20.96-2.75q-251.74-69.93-251.79-69.94c-0.06-0.02-0.12-0.04-0.18-0.05C480.19 316.35 466 304.95 466 282.8c0-24.61 35.1-31.59 44.31-32.99 9.93-4.91 31.47-14.74 60.73-4.73l66.26 21.89 116-90.16c3.61-2.81 8.32-4.13 12.91-3.62 3.88 0.43 7.7 0.78 11.4 1.11 9.67 0.88 19.67 1.78 31.08 4.24 4.53 0.97 8.18 4.15 9.77 8.49 1.58 4.32 0.86 9.08-1.95 12.73l-64.75 84.18c-3.37 4.38-9.65 5.2-14.02 1.83-4.38-3.37-5.2-9.65-1.83-14.02l58.1-75.53c-6.17-0.9-12.08-1.44-18.2-1.99-3.53-0.32-7.18-0.65-10.96-1.06l-119.49 92.87a9.997 9.997 0 0 1-9.27 1.6l-71.38-23.58s-0.07-0.02-0.11-0.04c-22.45-7.7-38.05 0.05-46.43 4.22l-0.42 0.21c-1.01 0.5-2.09 0.83-3.21 0.97-13.19 1.69-28.55 7.91-28.55 13.4 0 6.75 0 14.4 44.08 27.7 5.88 1.63 251.72 69.92 251.72 69.92 0.31 0.09 26.88 7.08 37.71-5.83l50.37-59.29-13.32-4.67-64.75 36.2a17.182 17.182 0 0 1-15.44 0.65l-61.93-27.57c-5.05-2.25-7.32-8.16-5.07-13.2 2.25-5.05 8.16-7.31 13.2-5.07l60.74 27.04 63.78-35.66c4.82-2.7 10.58-3.19 15.79-1.37l16.74 5.87c2.06 0.72 3.94 1.8 5.6 3.21 7.46 6.33 8.37 17.54 2.05 25l-52.47 61.76c-8.18 9.75-21.05 14.93-37.18 14.93z m-13.08-73.2h0.03-0.03z" fill="#333333" p-id="1594" data-darkreader-inline-fill="" style="--darkreader-inline-fill: #272a2b;"></path></svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,60 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M295.9,355.2c0,-99.1 80.3,-179.4 179.4,-179.4s179.4,80.3 179.4,179.4H295.9z"
android:fillColor="#D4EFFF"/>
<path
android:pathData="M647.4,371.5c0,-54 -77.1,-97.8 -172.1,-97.8s-172.1,43.8 -172.1,97.8h344.2z"
android:fillColor="#89CBF4"/>
<path
android:pathData="M436.8,226.8m38.5,0l0,0q38.5,0 38.5,38.5l0,42.7q0,38.5 -38.5,38.5l-0,0q-38.5,0 -38.5,-38.5l0,-42.7q0,-38.5 38.5,-38.5Z"
android:fillColor="#89CBF4"/>
<path
android:pathData="M256.3,362.1m41,0l356,0q41,0 41,41l0,26.8q0,41 -41,41l-356,0q-41,0 -41,-41l0,-26.8q0,-41 41,-41Z"
android:fillColor="#35A5F6"/>
<path
android:pathData="M273,471.2m41.7,0l321,0q41.7,0 41.7,41.7l0,289.8q0,41.7 -41.7,41.7l-321,0q-41.7,0 -41.7,-41.7l0,-289.8q0,-41.7 41.7,-41.7Z"
android:fillColor="#B1DCFD"/>
<path
android:pathData="M356.8,666.7m29.6,0l93.8,0q29.6,0 29.6,29.6l0,-0q0,29.6 -29.6,29.6l-93.8,0q-29.6,0 -29.6,-29.6l0,0q0,-29.6 29.6,-29.6Z"
android:fillColor="#35A5F6"/>
<path
android:pathData="M356.8,558.8m29.6,0l93.8,0q29.6,0 29.6,29.6l0,-0q0,29.6 -29.6,29.6l-93.8,0q-29.6,0 -29.6,-29.6l0,0q0,-29.6 29.6,-29.6Z"
android:fillColor="#35A5F6"/>
<path
android:pathData="M311.9,479.2v305.8s-1.9,20.8 17.3,20.8h302.3s31,1 42.5,-25v32.3s-11.6,28.4 -41.4,28.4h-329.1s-30.5,-7.5 -30.5,-35.1V499s5.1,-21.7 38.9,-19.8z"
android:fillColor="#89CBF4"/>
<path
android:pathData="M491.6,854.5H311.2c-26.6,0 -48.2,-21.6 -48.2,-48.2V509.4c0,-26.6 21.6,-48.2 48.2,-48.2h24.2c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-24.2c-15.5,0 -28.2,12.6 -28.2,28.2v297c0,15.5 12.6,28.2 28.2,28.2h180.4c5.5,0 10,4.5 10,10s-4.5,10 -10,10zM677.6,583.5c-5.5,0 -10,-4.5 -10,-10V509.4c0,-15.5 -12.6,-28.2 -28.2,-28.2H436.2c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h203.2c26.6,0 48.2,21.6 48.2,48.2v64.1c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M335,367.1s-24.4,2.5 -24.4,26.7v52.3s0.2,19 24.4,19h-54.3c-11.5,0 -20.8,-9.3 -20.8,-20.8v-56.4c0,-11.5 9.3,-20.8 20.8,-20.8H335z"
android:fillColor="#0080E0"/>
<path
android:pathData="M437.1,276s-68.4,14.4 -90.6,78h-43.4s28,-66.5 133.9,-78z"
android:fillColor="#71C2EA"/>
<path
android:pathData="M656.8,481H433.9c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h222.9c15.2,0 27.5,-12.4 27.5,-27.5v-33.8c0,-15.2 -12.4,-27.5 -27.5,-27.5h-363c-15.2,0 -27.5,12.4 -27.5,27.5v33.8c0,15.2 12.4,27.5 27.5,27.5h48.5c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-48.5c-26.2,0 -47.5,-21.3 -47.5,-47.5v-33.8c0,-26.2 21.3,-47.5 47.5,-47.5h363c26.2,0 47.5,21.3 47.5,47.5v33.8c0,26.2 -21.3,47.5 -47.5,47.5z"
android:fillColor="#333333"/>
<path
android:pathData="M295.9,365.5c-5.5,0 -10,-4.5 -10,-10 0,-104.4 85,-189.4 189.4,-189.4 41.2,0 80.4,13 113.3,37.6 31.8,23.8 55.8,57.7 67.6,95.4 1.6,5.3 -1.3,10.9 -6.6,12.5 -5.3,1.6 -10.9,-1.3 -12.5,-6.6 -10.5,-33.8 -32,-64.1 -60.4,-85.4 -29.4,-22 -64.5,-33.7 -101.3,-33.7 -93.4,0 -169.4,76 -169.4,169.4 0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M834,690.9v-6.7c0,-7.6 -6.2,-13.7 -13.7,-13.7s-13.7,-6.2 -13.7,-13.7S800.4,643 792.8,643s-13.7,-6.2 -13.7,-13.7 -6.2,-13.7 -13.7,-13.7 -13.7,-6.2 -13.7,-13.7 -6.2,-13.7 -13.7,-13.7h-6.7c-4.4,0 -8.6,2.1 -11.1,5.7l-34.8,48.2c-3.9,5.5 -3.3,13 1.4,17.7l75.6,75.6c4.8,4.8 12.3,5.4 17.7,1.4l48.2,-34.8c3.6,-2.6 5.7,-6.7 5.7,-11.1zM523.3,795.9v6.7c0,7.6 6.2,13.7 13.7,13.7s13.7,6.2 13.7,13.7 6.2,13.7 13.7,13.7 13.7,6.2 13.7,13.7 6.2,13.7 13.7,13.7 13.7,6.2 13.7,13.7 6.2,13.7 13.7,13.7h6.7c4.4,0 8.6,-2.1 11.1,-5.7l34.8,-48.2c3.9,-5.5 3.3,-13 -1.4,-17.7l-75.6,-75.6c-4.8,-4.8 -12.3,-5.4 -17.7,-1.4l-48.2,34.8c-3.6,2.6 -5.7,6.7 -5.7,11.1z"
android:fillColor="#F76C69"/>
<path
android:pathData="M745.4,676.3c52.9,52.9 53.2,81 0.3,133.9 -52.9,52.9 -80.7,52.4 -133.6,-0.6 -52.9,-52.9 -53.2,-80.4 -0.3,-133.4s80.7,-52.9 133.6,0z"
android:fillColor="#F76C69"/>
<path
android:pathData="M785.4,743c-3.1,0 -6.2,-1.4 -8.1,-4.2 -3.2,-4.5 -2.2,-10.7 2.3,-14l42.9,-30.9c1,-0.7 1.5,-1.8 1.5,-3v-6.7a3.7,3.7 0,0 0,-3.7 -3.7c-13.1,0 -23.7,-10.6 -23.7,-23.7a3.7,3.7 0,0 0,-3.7 -3.7c-13.1,0 -23.7,-10.6 -23.7,-23.7a3.7,3.7 0,0 0,-3.7 -3.7c-13.1,0 -23.7,-10.6 -23.7,-23.7a3.7,3.7 0,0 0,-3.7 -3.7h-6.7c-1.2,0 -2.3,0.6 -3,1.5L698,641.5c-3.2,4.5 -9.5,5.5 -14,2.3s-5.5,-9.5 -2.3,-14l30.2,-41.8c4.4,-6.2 11.6,-9.9 19.3,-9.9h6.7c13.1,0 23.7,10.6 23.7,23.7a3.7,3.7 0,0 0,3.7 3.7c13.1,0 23.7,10.6 23.7,23.7a3.7,3.7 0,0 0,3.7 3.7c13.1,0 23.7,10.6 23.7,23.7a3.7,3.7 0,0 0,3.7 3.7c13.1,0 23.7,10.6 23.7,23.7v6.7c0,7.6 -3.7,14.8 -9.9,19.3l-42.9,30.9a10,10 0,0 1,-5.8 1.9zM626.2,908.7h-6.7c-13.1,0 -23.7,-10.6 -23.7,-23.7a3.7,3.7 0,0 0,-3.7 -3.7c-13.1,0 -23.7,-10.6 -23.7,-23.7a3.7,3.7 0,0 0,-3.7 -3.7c-13.1,0 -23.7,-10.6 -23.7,-23.7a3.7,3.7 0,0 0,-3.7 -3.7c-13.1,0 -23.7,-10.6 -23.7,-23.7v-6.7c0,-7.6 3.7,-14.8 9.9,-19.3l41.8,-30.1c4.5,-3.2 10.7,-2.2 14,2.3 3.2,4.5 2.2,10.7 -2.3,14l-41.8,30.1c-1,0.7 -1.5,1.8 -1.5,3v6.7a3.7,3.7 0,0 0,3.7 3.7c13.1,0 23.7,10.6 23.7,23.7a3.7,3.7 0,0 0,3.7 3.7c13.1,0 23.7,10.6 23.7,23.7a3.7,3.7 0,0 0,3.7 3.7c13.1,0 23.7,10.6 23.7,23.7a3.7,3.7 0,0 0,3.7 3.7h6.7c1.2,0 2.3,-0.6 3,-1.5l30.2,-41.9c3.2,-4.5 9.5,-5.5 14,-2.3s5.5,9.5 2.3,14l-30.2,41.9c-4.4,6.2 -11.6,9.9 -19.3,9.9z"
android:fillColor="#333333"/>
<path
android:pathData="M674.1,647.4s-46.2,53.5 -54.9,78.5c0,0 -7.7,15.3 0,28.8 0,0 21,57.3 63.5,89.8 0,0 -20.7,5 -33.4,0 0,0 -82.6,-56.5 -77,-107.3 0,0 35.4,-85.4 101.9,-89.8z"
android:fillColor="#E54E4E"/>
<path
android:pathData="M679.3,859.7h-0.4c-22.1,-0.2 -43.5,-12.6 -73.8,-42.9 -30.3,-30.3 -42.7,-51.7 -42.8,-73.7 -0.1,-22.1 12.2,-43.5 42.5,-73.8 30.3,-30.3 51.7,-42.6 73.9,-42.6s43.6,12.4 73.9,42.6c3.9,3.9 3.9,10.2 0,14.1s-10.2,3.9 -14.1,0c-25.8,-25.8 -43.7,-36.8 -59.8,-36.8s-34,11 -59.8,36.8c-25.7,25.7 -36.7,43.5 -36.6,59.6 0.1,16 11.1,33.8 36.9,59.6 25.9,25.9 43.8,37 59.8,37.1h0.3c16.1,0 33.9,-10.9 59.4,-36.5 20.4,-20.4 31.2,-35.4 35,-48.8 3.7,-12.7 1,-25 -8.7,-39.8 -3,-4.6 -1.8,-10.8 2.9,-13.9s10.8,-1.8 13.9,2.9c28,42.7 9.7,75.1 -28.9,113.7 -30,30 -51.4,42.3 -73.5,42.3z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,57 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M327.4,462.9V511H254.1c-7.4,0 -13.5,6 -13.5,13.5v184.1c0,7.4 6,13.5 13.5,13.5h73.3v48.1H254.1c-33.9,0 -61.5,-27.6 -61.5,-61.5V524.5c0,-33.9 27.6,-61.5 61.5,-61.5h73.3z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M253.9,732.4c-12.9,0 -23.5,-10.5 -23.5,-23.5V524.8c0,-12.9 10.5,-23.5 23.5,-23.5h28c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-28c-1.9,0 -3.5,1.6 -3.5,3.5v184.1c0,1.9 1.6,3.5 3.5,3.5 5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M281.9,780.5h-28c-39.5,0 -71.6,-32.1 -71.6,-71.6V524.8c0,-39.5 32.1,-71.6 71.6,-71.6 5.5,0 10,4.5 10,10s-4.5,10 -10,10c-28.4,0 -51.5,23.1 -51.5,51.5v184.1c0,28.4 23.1,51.5 51.5,51.5h28c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M316,405h408.1v337.5c0,48.3 -39.2,87.5 -87.5,87.5H403.5c-48.3,0 -87.5,-39.2 -87.5,-87.5V405z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M407,525m37.5,0l0,0q37.5,0 37.5,37.5l0,143q0,37.5 -37.5,37.5l0,0q-37.5,0 -37.5,-37.5l0,-143q0,-37.5 37.5,-37.5Z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M559,525m37.5,0l0,0q37.5,0 37.5,37.5l0,143q0,37.5 -37.5,37.5l0,0q-37.5,0 -37.5,-37.5l0,-143q0,-37.5 37.5,-37.5Z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M714.8,273.3c-4,0 -8,0.4 -11.8,1.1 -4.6,-44.1 -41.8,-78.5 -87.1,-78.5 -26.6,0 -50.3,11.8 -66.4,30.5 -15.8,-35.6 -51.4,-60.4 -92.9,-60.4 -48.5,0 -89.1,34 -99.2,79.6a81.2,81.2 0,0 0,-17.3 -1.9c-43.5,0 -79,34.5 -80.6,77.7h-0.1v122.5c0,47.8 38.8,86.7 86.7,86.7 47.8,0 86.7,-38.8 86.7,-86.7v-38.8h274.9v-0.4c2.4,0.3 4.8,0.4 7.2,0.4 36.4,0 65.9,-29.5 65.9,-65.9s-29.5,-65.9 -65.9,-65.9z"
android:fillColor="#FFF6DB"/>
<path
android:pathData="M348,252s-49,19 -49,60v139.5s6,41 49,41c0,0 54,4.4 76,-36.5 0,0 -4.7,69 -77.3,69 0,0 -85.5,-1.6 -85.5,-74.3V307.7S282,236 348,252zM433,364h274s46,2 66,-33c0,0 6.2,61.3 -65.4,74.6H433V364z"
android:fillColor="#F8E0BB"/>
<path
android:pathData="M359,521v212.3S358,789 402,789h247s47,-3 71,-47c0,0 -3,87 -74,87H398.9S318,814 318,743V533.5L359,521z"
android:fillColor="#F29816"/>
<path
android:pathData="M513,840H408.6C352,840 306,794 306,737.4V525.5c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v211.9c0,45.5 37,82.6 82.6,82.6H513c5.5,0 10,4.5 10,10s-4.5,10 -10,10zM724.1,595c-5.5,0 -10,-4.5 -10,-10V462c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v123c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M346.1,540.5c-53.3,0 -96.7,-43.4 -96.7,-96.7v-122.5c0,-0.6 0.1,-1.1 0.1,-1.7 1.2,-23 10.9,-44.5 27.5,-60.5 17,-16.4 39.4,-25.5 63,-25.5h0.9c5.4,0 10.3,-3.3 12.4,-8.4C370.6,183.2 411.1,156 456.6,156c39.3,0 75.4,20.7 95.4,53.7a97.5,97.5 0,0 1,63.9 -23.8c45.2,0 84.2,30.7 94.8,74.6 0.4,1.7 1.8,2.8 3.6,2.8h0.5c20,0 38.9,7.7 53.1,21.7 14.3,14 22.3,32.7 22.7,52.6 0.4,20.3 -7.3,39.5 -21.6,54.2 -14.7,15 -34.3,23.2 -55.3,23.2h-234.1c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h234.1c15.6,0 30.1,-6.1 41,-17.2 10.6,-10.8 16.2,-24.9 15.9,-39.8 -0.3,-14.7 -6.2,-28.4 -16.7,-38.7 -10.5,-10.3 -24.4,-16 -39.1,-16h-0.5c-11,0 -20.4,-7.4 -23,-18.1 -8.4,-34.9 -39.5,-59.3 -75.4,-59.3 -22.6,0 -44,9.9 -58.8,27a10,10 0,0 1,-9 3.4c-3.4,-0.5 -6.3,-2.7 -7.7,-5.8 -14.7,-33.1 -47.6,-54.5 -83.7,-54.5s-70.6,22.3 -84.8,56.9c-5.2,12.7 -17.3,20.8 -30.9,20.8H340.1c-18.4,0 -35.8,7 -49.1,19.8 -13.2,12.8 -20.8,29.9 -21.5,48.2 -0,0.3 -0,0.6 -0.1,0.9v121.3c0,42.3 34.4,76.7 76.7,76.7s76.7,-34.4 76.7,-76.7v-79.5c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v79.5c0,53.3 -43.4,96.7 -96.7,96.7z"
android:fillColor="#333333"/>
<path
android:pathData="M530.3,291.1c-5.5,0 -10,-4.5 -10,-10 0,-52.3 42.5,-94.8 94.8,-94.8 5.5,0 10,4.5 10,10s-4.5,10 -10,10c-41.3,0 -74.8,33.6 -74.8,74.8 0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M777.5,692.1l71.8,-83.9c3.6,2.8 8.8,2.3 11.8,-1.3l11,-13.3a8.5,8.5 0,0 0,-0.5 -11.5l-36,-36c-3.1,-3.1 -8.1,-3.3 -11.5,-0.5l-13.3,11c-3.6,3 -4.1,8.2 -1.3,11.8l-83.9,71.8c-16,-13.2 -39.6,-12.3 -54.6,2.7L559.6,754.3c-15.9,15.9 -15.9,41.6 0,57.5l46.3,46.3c15.9,15.9 41.6,15.9 57.5,0L774.9,746.6c14.9,-14.9 15.8,-38.6 2.7,-54.6z"
android:fillColor="#54D533"/>
<path
android:pathData="M562,764l67.5,67.5s9.6,12.1 21.7,0l130.8,-128.8c10.4,10.7 10.3,27.8 -0.3,38.3L663.4,858s-27.3,27.4 -50.7,4l-58.4,-58.4s-13.3,-27.7 7.7,-39.7z"
android:fillColor="#44A00E"/>
<path
android:pathData="M634.7,880c-13.5,0 -26.3,-5.3 -35.8,-14.8l-46.3,-46.3c-9.6,-9.6 -14.8,-22.3 -14.8,-35.8s5.3,-26.3 14.8,-35.8l111.4,-111.4c16.5,-16.5 41.4,-19.4 61,-8.2l72.8,-62.3c-0.7,-6 1.6,-12.2 6.6,-16.3l13.3,-11c7.4,-6.1 18.1,-5.6 24.9,1.2l36,36c6.8,6.8 7.3,17.5 1.2,24.9l-11,13.3c-4.2,5 -10.3,7.3 -16.3,6.6l-62.3,72.9c11.3,19.5 8.3,44.5 -8.2,61L670.5,865.2c-9.6,9.6 -22.3,14.8 -35.8,14.8zM699.8,640.9c-7.9,0 -15.7,3 -21.7,9L566.7,761.3c-11.9,11.9 -11.9,31.4 0,43.3l46.3,46.3c5.8,5.8 13.5,9 21.7,9s15.9,-3.2 21.7,-9l111.4,-111.4c11.2,-11.2 12.1,-28.9 2,-41.1a10,10 0,0 1,0.1 -12.9l71.8,-83.9c3.2,-3.7 8.4,-4.5 12.5,-2.2l9.3,-11.3 -34.1,-34.1 -11.3,9.3c2.3,4.1 1.5,9.4 -2.2,12.5l-83.9,71.8a10,10 0,0 1,-12.9 0.1c-5.7,-4.7 -12.6,-7 -19.5,-7z"
android:fillColor="#333333"/>
<path
android:pathData="M713.8,712.7l40,40 -86.3,86.3 -40,-40c-4.8,-4.8 -4.8,-12.7 0,-17.5l68.7,-68.7c4.8,-4.8 12.7,-4.8 17.5,0z"
android:fillColor="#D8F9CC"/>
<path
android:pathData="M742,741l12,12L668,839l-12,-12z"
android:fillColor="#BFEAAD"/>
</vector>

View File

@@ -0,0 +1,42 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M282.4,226.3h206.2V835.3H282.4c-37.3,0 -67.6,-30.3 -67.6,-67.6V293.9c0,-37.3 30.3,-67.6 67.6,-67.6z"
android:fillColor="#57B7F9"/>
<path
android:pathData="M693.7,835.3H487.5V226.3h206.2c37.3,0 67.6,30.3 67.6,67.6V767.7c0,37.3 -30.3,67.6 -67.6,67.6z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M487.9,347.7l120.6,-161.6H367.3l120.6,161.6z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M367.3,186.1l120.6,161.6 -67.8,42.4c-7.7,4.8 -18,1.2 -20.9,-7.4l-50.5,-147.8a22.1,22.1 0,0 1,1.6 -17.8l17.1,-31zM608.8,186.1l-120.6,161.6 67.8,42.4c7.7,4.8 18,1.2 20.9,-7.4l50.5,-147.8a22.1,22.1 0,0 0,-1.6 -17.8l-17.1,-31z"
android:fillColor="#A1DCFF"/>
<path
android:pathData="M414.7,400.3c-3,0 -6.1,-0.5 -9.1,-1.6 -7.8,-2.8 -13.8,-8.8 -16.5,-16.6l-41.4,-119.2c-1.8,-5.2 0.9,-10.9 6.2,-12.7 5.2,-1.8 10.9,0.9 12.7,6.2l41.4,119.2c1,2.8 3.1,3.9 4.3,4.3 1.2,0.4 3.6,0.9 6.1,-0.6l52.4,-32.5c10.6,-6.6 24.3,-6.5 34.9,0.2l50.5,32.2c2.5,1.6 4.9,1.1 6.1,0.7 1.2,-0.4 3.3,-1.5 4.3,-4.3l43.1,-119.2c1.9,-5.2 7.6,-7.9 12.8,-6 5.2,1.9 7.9,7.6 6,12.8l-43.1,119.2c-2.8,7.8 -8.9,13.8 -16.7,16.4 -7.8,2.7 -16.3,1.6 -23.3,-2.8l-50.5,-32.2c-4.1,-2.6 -9.4,-2.7 -13.6,-0.1l-52.4,32.5c-4.3,2.7 -9.3,4.1 -14.2,4.1zM488.1,732c-5.5,0 -10,-4.5 -10,-10V415.7c0,-5.5 4.5,-10 10,-10s10,4.5 10,10V722c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M257.3,239.9v530s-1.6,25.6 29.6,25.6h159.6V836H275.7s-56.4,-16.1 -56.4,-66V282.7s5.2,-38.8 38,-42.7z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M373,845.3h-85.2c-45.2,0 -82,-36.8 -82,-82V298.3c0,-45.2 36.8,-82 82,-82h53.3c0.7,0 1.4,-0.4 1.7,-1 4.3,-8.9 9.5,-19.3 13.1,-26.5 3.9,-7.8 11.8,-12.7 20.5,-12.7h225.2c8.8,0 16.6,4.9 20.5,12.7l13.3,26.5c0.3,0.6 0.9,1 1.7,1h53.4c45.2,0 82,36.8 82,82v319.7c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V298.3c0,-34.2 -27.8,-62 -62,-62h-53.4c-8.3,0 -15.8,-4.6 -19.5,-12.1l-13.3,-26.5c-0.5,-1 -1.5,-1.6 -2.6,-1.6H376.4c-1.1,0 -2.1,0.6 -2.6,1.6 -3.6,7.1 -8.7,17.5 -13,26.3 -3.6,7.5 -11.4,12.3 -19.7,12.3H287.8c-34.2,0 -62,27.8 -62,62v465.1c0,34.2 27.8,62 62,62H373c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M848.3,817.2l-5.1,-100.3s-1.9,-12.9 -12.2,-6.4c0,0 -26.4,35.3 -63,26.4 0,0 -39.4,-6.7 -38.5,-50.1 0,0 4.1,-33.7 -13.5,-33.4 0,0 -12.4,-3.6 -16.1,21.2 0,0 -1.4,23.5 -22.5,37.3 0,0 -54.1,36.6 -188.7,71.2 0,0 -20,6.1 -46.5,11.7 0,0 -21,5.8 -16.6,22.5 0,0 1.3,34.7 44.6,51.6 11.8,4.6 24.5,6.9 37.2,6.9h285.1s63.5,7.1 55.8,-58.5z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M592.5,805.5c-2.3,0 -4.6,-0.8 -6.5,-2.4l-29.6,-25.6c-4.2,-3.6 -4.6,-9.9 -1,-14.1 3.6,-4.2 9.9,-4.6 14.1,-1l29.6,25.6c4.2,3.6 4.6,9.9 1,14.1a10,10 0,0 1,-7.6 3.5zM643.9,782.6c-2.3,0 -4.6,-0.8 -6.5,-2.4l-29.6,-25.6c-4.2,-3.6 -4.6,-9.9 -1,-14.1 3.6,-4.2 9.9,-4.6 14.1,-1l29.6,25.6c4.2,3.6 4.6,9.9 1,14.1a10,10 0,0 1,-7.6 3.5zM699.1,757.2c-2.3,0 -4.6,-0.8 -6.5,-2.4l-29.6,-25.6c-4.2,-3.6 -4.6,-9.9 -1,-14.1 3.6,-4.2 9.9,-4.6 14.1,-1l29.6,25.6c4.2,3.6 4.6,9.9 1,14.1a10,10 0,0 1,-7.6 3.5z"
android:fillColor="#333333"/>
<path
android:pathData="M436,829s32.8,9.9 220.9,10.9c0,0 140.1,-9.9 191.1,-28 0,0 11.3,56 -42.3,63.5l-298.3,0.2S448,874 436,829z"
android:fillColor="#FC981C"/>
<path
android:pathData="M797.7,885.9c-2.7,0 -4.7,-0.1 -5.6,-0.2L507.4,885.7c-14.3,0 -28,-2.5 -40.8,-7.5 -44.7,-17.5 -50.2,-52.3 -50.8,-59.3 -2.4,-10.4 1.4,-20.3 10.6,-27.1 6.1,-4.5 12.6,-6.4 13.3,-6.6 0.2,-0.1 0.4,-0.1 0.6,-0.1 25.7,-5.5 45.5,-11.5 45.7,-11.5l0.4,-0.1c130.8,-33.6 185.1,-69.4 185.6,-69.8 0,-0 0.1,-0.1 0.1,-0.1 16.4,-10.7 17.9,-28.8 18,-29.5 0,-0.3 0,-0.5 0.1,-0.8 1.9,-13.1 6.6,-22.1 13.7,-26.8 4.7,-3 9.7,-3.5 13.3,-3 5.8,0.2 10.8,2.6 14.7,6.8 9.9,11 8.3,31.9 7.7,37.2 -0.2,14.1 4.6,24.9 14.2,32.2 7.7,5.8 15.9,7.4 16,7.4 0.2,0 0.4,0.1 0.6,0.1 12.1,3 24.5,0.2 36.8,-8.1 9.8,-6.7 15.9,-14.5 15.9,-14.6 0.7,-1 1.7,-1.8 2.7,-2.5 7.8,-4.9 14,-3.3 17,-1.9 8.3,3.8 10.1,13.4 10.4,15.3 0.1,0.3 0.1,0.6 0.1,1l5.1,99.9c2.6,22.7 -2.3,40.4 -14.5,52.7 -14.7,14.8 -35.8,16.8 -46.2,16.8zM444.7,804.4c-0.8,0.3 -4,1.4 -6.7,3.5 -3.4,2.7 -3.2,4.8 -2.7,6.7 0.2,0.8 0.3,1.4 0.3,2.2 0.1,1.1 2.1,28.5 38.2,42.7 10.4,4.1 21.7,6.2 33.5,6.2h285.1c0.4,0 0.7,0 1.1,0.1 0.2,0 23.2,2.3 36.1,-10.8 7.7,-7.8 10.6,-20.1 8.7,-36.5 -0,-0.2 -0,-0.4 -0.1,-0.7l-4.9,-94.9c-10.5,11 -35.3,31.5 -67.6,23.8 -2.4,-0.5 -12.9,-2.8 -23.4,-10.5 -10.8,-7.9 -23.6,-22.9 -23,-49.7 0,-0.3 0,-0.7 0.1,-1 1.2,-9.9 -0.6,-20.9 -2.9,-22.2s-0.1,-0.1 -0.5,-0.1c-0.6,0 -1.1,-0 -1.6,-0.1 -0.6,0.5 -3.2,3.1 -4.6,12.5 -0.4,4.2 -3.5,29.2 -26.9,44.5 -3.2,2.1 -58.2,38.2 -191.5,72.4 -2.4,0.7 -21.5,6.4 -46.7,11.8zM713.3,663zM713.2,662.9s0.1,0 0.1,0c-0,0 -0.1,-0 -0.1,-0z"
android:fillColor="#333333"/>
<path
android:pathData="M520.6,850c-3.4,0 -6.7,0 -9.9,-0 -5.5,-0 -10,-4.5 -10,-10 0,-5.5 4.5,-10 10,-10h0c289.4,0.7 324.2,-24.7 328.2,-29.8 3.4,-4.3 9.7,-5.1 14.1,-1.6 4.3,3.4 5.1,9.7 1.6,14.1 -7.3,9.2 -24,16.1 -52.6,21.6 -22.4,4.3 -52.3,7.8 -89.1,10.4 -64,4.5 -138.2,5.5 -192.4,5.5z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,60 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M198.9,437.1m53.7,0l463.2,0q53.7,0 53.7,53.7l0,251q0,53.7 -53.7,53.7l-463.2,0q-53.7,0 -53.7,-53.7l0,-251q0,-53.7 53.7,-53.7Z"
android:fillColor="#EA5959"/>
<path
android:pathData="M199.4,553.7S260,595 352.8,533.7c0,0 119.2,92.3 260,0 0,0 75.9,55.4 156.7,21.4V436.3H200.2l-0.8,117.3z"
android:fillColor="#CE4141"/>
<path
android:pathData="M612.9,483.2c-72.5,70.2 -187.6,70.2 -260,0S394.8,219 394.8,219h176.1l41.9,264.2z"
android:fillColor="#FEC773"/>
<path
android:pathData="M251.1,219h143.7l-41.9,264.2c-45.5,59.6 -133.1,65.3 -185.9,12.1a31.8,31.8 0,0 1,-8.6 -28.7l41.6,-205.7c4.9,-24.4 26.3,-41.9 51.2,-41.9z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M247.3,226.7l-42.5,238.3s15.9,21.3 52.1,21.3c0,0 55,5 98.2,-49.1L349,487s-31.3,46.1 -93,45c0,0 -67.2,-3.2 -91.7,-58.5l43.6,-215.9s9.6,-27.6 39.3,-30.8z"
android:fillColor="#F29816"/>
<path
android:pathData="M366.4,444.7s60.6,48.6 117,47.7c0,0 79.8,-5.2 119.1,-48.8l9.4,35.3s-36,48.5 -132.7,52.9c0,0 -75.5,-3.1 -120.2,-47.8l7.4,-39.3z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M485.1,545.8c-51.4,0 -100,-19.7 -137,-55.4a10,10 0,0 1,-2.9 -8.8l41.9,-264.2a10,10 0,0 1,9.9 -8.4h176.1c4.9,0 9.1,3.6 9.9,8.4L625,481.7c0.5,3.2 -0.6,6.5 -2.9,8.8 -36.9,35.7 -85.6,55.4 -137,55.4zM365.8,479.6c32.7,29.9 74.8,46.3 119.3,46.3s86.6,-16.4 119.3,-46.3L564.6,229L405.6,229l-39.8,250.6z"
android:fillColor="#333333"/>
<path
android:pathData="M235,554v190S235,763 255,763h504c0,20.5 -16.7,37.2 -37.2,37.2H249.4s-51,-5.7 -51,-51V523L235,554z"
android:fillColor="#CE4141"/>
<path
android:pathData="M717.1,810.2H253.9c-35.1,0 -63.7,-28.6 -63.7,-63.7V584c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v162.5c0,24.1 19.6,43.7 43.7,43.7h463.1c5.5,0 10,4.5 10,10s-4.5,10 -10,10zM770.8,648.3c-5.5,0 -10,-4.5 -10,-10V495.5c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v142.8c0,5.5 -4.5,10 -10,10zM256.7,541.8c-4.9,0 -9.9,-0.3 -14.9,-0.8 -30.5,-3.4 -58.1,-16.8 -79.8,-38.7a41.7,41.7 0,0 1,-11.3 -37.7l41.6,-205.7c5.8,-28.9 31.5,-49.9 61,-49.9h143.7c2.9,0 5.7,1.3 7.6,3.5s2.7,5.2 2.3,8.1L365,484.8c-0.9,5.4 -6,9.2 -11.4,8.3 -5.4,-0.9 -9.2,-6 -8.3,-11.4l40.1,-252.7H253.4c-20,0 -37.4,14.2 -41.4,33.9L170.4,468.6c-1.4,7.1 0.8,14.5 5.9,19.7 18.4,18.6 41.9,30 67.8,32.9 24.9,2.8 50.4,-2.8 71.7,-15.7 4.7,-2.9 10.9,-1.4 13.7,3.4 2.9,4.7 1.4,10.9 -3.4,13.7 -20.8,12.6 -45,19.3 -69.5,19.3z"
android:fillColor="#333333"/>
<path
android:pathData="M425.7,614h119.6c15.3,0 27.7,12.4 27.7,27.7V789H398V641.7c0,-15.3 12.4,-27.7 27.7,-27.7z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M573,799c-5.5,0 -10,-4.5 -10,-10V641.7c0,-9.8 -7.9,-17.7 -17.7,-17.7H425.7c-9.8,0 -17.7,7.9 -17.7,17.7V750c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V641.7c0,-20.8 16.9,-37.7 37.7,-37.7h119.6c20.8,0 37.7,16.9 37.7,37.7V789c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M714.3,219H570.6l41.9,264.2c45.5,59.6 133.1,65.3 185.9,12.1a31.8,31.8 0,0 0,8.6 -28.7l-41.6,-205.7c-4.9,-24.4 -26.3,-41.9 -51.2,-41.9z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M615.1,443.7s42.7,40.4 100.1,40.4c0,0 54.2,-6.4 83,-33l8.5,29.4s-25.7,45.1 -95.8,46.2c0,0 -43.9,6.8 -95.8,-43.4v-39.5z"
android:fillColor="#F29816"/>
<path
android:pathData="M713,541.8a133.4,133.4 0,0 1,-106.2 -52.5c-1,-1.3 -1.7,-2.9 -1.9,-4.5l-41.9,-264.2c-0.5,-2.9 0.4,-5.8 2.3,-8.1s4.7,-3.5 7.6,-3.5h143.7c29.5,0 55.1,21 61,49.9l41.6,205.7a41.7,41.7 0,0 1,-11.3 37.7,133.4 133.4,0 0,1 -94.8,39.5zM624.3,479.1a113.4,113.4 0,0 0,81.4 42.5,113.4 113.4,0 0,0 87.9,-33.4 21.8,21.8 0,0 0,5.9 -19.7l-41.6,-205.7c-4,-19.6 -21.4,-33.9 -41.4,-33.9L584.6,229l39.7,250.1z"
android:fillColor="#333333"/>
<path
android:pathData="M813.2,859H668.5c-28.3,0 -49,-26.6 -42.2,-54l19.8,-79c4.8,-19.3 22.2,-32.9 42.2,-32.9h144.7c28.3,0 49,26.6 42.2,54l-19.8,79c-4.8,19.3 -22.2,32.9 -42.2,32.9z"
android:fillColor="#57B7F9"/>
<path
android:pathData="M684,754.2c-1.4,-1.7 -1.7,-3.9 -0.7,-6.6 1.5,-4 3.8,-7.6 6.8,-10.9s6.7,-5.8 10.8,-7.7c4.1,-1.9 8.4,-2.8 12.9,-2.8 5.6,0 10.8,1.4 15.5,4.2 4.7,2.8 8.5,6.6 11.3,11.2 2.8,4.7 4.2,9.7 4.2,14.9 0,4.3 -0.9,8.5 -2.7,12.6 -1.8,4 -4.7,8.3 -8.7,12.9l-32,34.7v-9.8h35.9c2.7,0 4.8,0.7 6.2,2.2 1.4,1.4 2.2,3.5 2.2,6.2v0.3c0,2.7 -0.7,4.8 -2.2,6.2 -1.4,1.4 -3.5,2.2 -6.2,2.2h-44.3c-2.8,0 -5,-0.7 -6.6,-2 -1.6,-1.3 -2.4,-3.2 -2.4,-5.5v-0.3c0,-2.1 0.4,-4 1.2,-5.8 0.8,-1.8 2.1,-3.7 3.9,-5.7l31.1,-33.8c2.9,-3.1 4.8,-5.7 5.8,-7.7 1,-2 1.5,-4.2 1.5,-6.6 0,-2.8 -0.5,-5.2 -1.6,-7.2 -1.1,-2 -2.6,-3.6 -4.6,-4.7 -2,-1.1 -4.4,-1.6 -7.3,-1.6 -1.9,0 -3.7,0.3 -5.3,0.8 -1.6,0.5 -3.1,1.3 -4.3,2.2 -1.3,0.9 -2.3,2.1 -3.2,3.4 -1.4,2.4 -2.8,4.2 -4.3,5.4 -1.5,1.2 -3.5,1.8 -5.8,1.8h-0.4c-2.9,0 -5,-0.8 -6.4,-2.5zM817.6,790.2c1.4,1.4 2.2,3.5 2.2,6.2v0.3c0,2.7 -0.7,4.7 -2.2,6.2 -1.4,1.4 -3.5,2.1 -6.2,2.1h-0.3v10.5c0,2.8 -0.7,4.9 -2.2,6.4s-3.6,2.2 -6.4,2.2h-0.3c-2.8,0 -4.9,-0.7 -6.4,-2.2 -1.5,-1.5 -2.2,-3.6 -2.2,-6.4v-10.5h-30.5c-2.8,0 -4.9,-0.6 -6.4,-1.7 -1.5,-1.1 -2.2,-2.7 -2.2,-4.8v-0.6c0,-2.1 0.2,-3.9 0.7,-5.5 0.5,-1.6 1.3,-3.3 2.4,-5.1l34.3,-54c1.2,-1.9 2.7,-3.3 4.3,-4.2 1.7,-0.9 3.7,-1.4 6,-1.4h0.1c2.8,0 4.9,0.7 6.4,2.2 1.5,1.5 2.2,3.6 2.2,6.4v51.7h0.3c2.7,0 4.8,0.7 6.2,2.2zM793.8,788L793.8,760.1l-17.3,28h17.3z"
android:fillColor="#333333"/>
<path
android:pathData="M679.6,701.5L652,816s-4,16.6 14.8,16.6h186.4s-11.7,26.4 -39.9,26.4h-149.8s-38.4,-9.9 -38.4,-44l24.4,-98s11.8,-15.6 30.2,-15.6z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M813.2,869H668.5c-16.6,0 -31.9,-7.5 -42.1,-20.6 -10.2,-13.1 -13.7,-29.8 -9.7,-45.9l19.8,-79a53.4,53.4 0,0 1,51.8 -40.5h144.7c16.6,0 31.9,7.5 42.1,20.6 10.2,13.1 13.7,29.8 9.7,45.9l-12.1,48.5c-1.3,5.4 -6.8,8.6 -12.1,7.3 -5.4,-1.3 -8.6,-6.8 -7.3,-12.1l12.1,-48.5c2.5,-10.1 0.3,-20.5 -6.1,-28.7 -6.4,-8.2 -16,-12.9 -26.4,-12.9H688.2a33.4,33.4 0,0 0,-32.5 25.3l-19.8,79c-2.5,10.1 -0.3,20.5 6.1,28.7 6.4,8.2 16,12.9 26.4,12.9H813.2c7.4,0 14.7,-2.5 20.6,-7.1 4.3,-3.4 10.6,-2.6 14,1.7s2.6,10.6 -1.7,14c-9.4,7.3 -21,11.3 -32.9,11.3z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,51 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M189.7,387.6m51.5,0l469.3,0q51.5,0 51.5,51.5l0,325.3q0,51.5 -51.5,51.5l-469.3,0q-51.5,0 -51.5,-51.5l0,-325.3q0,-51.5 51.5,-51.5Z"
android:fillColor="#EA5959"/>
<path
android:pathData="M448.9,498h313.2v207.3H448.9c-28.4,0 -51.5,-23.1 -51.5,-51.5V549.5c0,-28.4 23.1,-51.5 51.5,-51.5z"
android:fillColor="#FEC773"/>
<path
android:pathData="M552,715.3H448.9c-33.9,0 -61.5,-27.6 -61.5,-61.5V549.5c0,-33.9 27.6,-61.5 61.5,-61.5H762c5.5,0 10,4.5 10,10s-4.5,10 -10,10H448.9c-22.9,0 -41.5,18.6 -41.5,41.5v104.4c0,22.9 18.6,41.5 41.5,41.5H552c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M281.4,321.8H670.2c21.6,0 39.2,17.6 39.2,39.2v26.8h-467.2v-26.8c0,-21.6 17.6,-39.2 39.2,-39.2z"
android:fillColor="#CE4141"/>
<path
android:pathData="M648,321.8S626.4,175.6 440.3,160.8c-9.7,-0.8 -16.1,9.3 -10.3,16.5 1,1.3 1.9,2.5 2.8,3.9 6.3,9.9 9.3,26.8 -8.4,32.5 0,0 -105.3,27.6 -120.7,108.2h344.3z"
android:fillColor="#FEC773"/>
<path
android:pathData="M439.5,217S371,258 371,314h-67.3s32.3,-97 135.8,-97z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M761.9,564c-5.5,0 -10,-4.5 -10,-10V439c0,-22.9 -18.6,-41.5 -41.5,-41.5h-1c-5.5,0 -10,-4.5 -10,-10V361c0,-16.1 -13.1,-29.2 -29.2,-29.2H303.7c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h366.5c27.1,0 49.2,22.1 49.2,49.2v17.2c29.7,4.3 52.5,30 52.5,60.8V554c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M247.9,350.5c-1.8,0 -3.6,-0.5 -5.2,-1.5 -4.7,-2.9 -6.2,-9 -3.3,-13.8 9,-14.7 24.7,-23.5 42,-23.5h14.3c8.8,-32.5 32.5,-61 68.9,-82.9 27.8,-16.7 53.6,-24 56.9,-24.9 4.7,-1.5 5.4,-3.7 5.7,-4.5 1.1,-3.2 -0,-8.6 -2.9,-13.1 -0.6,-1 -1.3,-2 -2.2,-3 -5,-6.3 -5.8,-14.5 -2.1,-21.5 4,-7.5 12.2,-11.9 21,-11.2 53.5,4.3 99,19.6 135.3,45.5 27,19.3 48.3,44 63.6,73.3a10,10 0,0 1,-4.3 13.5c-4.9,2.5 -10.9,0.6 -13.5,-4.3 -23,-44.5 -73.4,-99.4 -182.7,-108.1 -0.9,-0.1 -1.4,0.3 -1.6,0.5 1.2,1.5 2.3,3 3.3,4.6 6.3,10 8.2,21.4 4.8,30.6 -2,5.6 -6.9,13 -18.6,16.8l-0.5,0.2c-0.2,0.1 -25.6,6.9 -52.4,23 -34.7,21 -55.2,47 -61,77.3a10,10 0,0 1,-9.8 8.1h-22.3c-10.3,0 -19.6,5.2 -24.9,14a10,10 0,0 1,-8.5 4.8zM437.7,170.9z"
android:fillColor="#333333"/>
<path
android:pathData="M232,393v366S232,778 252,778h504c0,20.5 -16.7,37.2 -37.2,37.2H246.4s-51,-5.7 -51,-51V428.5c0,-20 16.5,-36.1 36.5,-35.5z"
android:fillColor="#CE4141"/>
<path
android:pathData="M557,825.8H241.2c-33.9,0 -61.5,-27.6 -61.5,-61.5V439c0,-33.9 27.6,-61.5 61.5,-61.5h376.9c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-376.9c-22.9,0 -41.5,18.6 -41.5,41.5v325.2c0,22.9 18.6,41.5 41.5,41.5H557c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M736,743m-140.7,0a140.7,140.7 0,1 0,281.4 0,140.7 140.7,0 1,0 -281.4,0Z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M709,610s-71,34 -71,143c0,0 1.9,118.5 123.9,118.5 0,0 -140.4,52.5 -166.6,-128.5 0,0 -0.3,-123 113.7,-133z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M736,893.7c-40.3,0 -78.1,-15.7 -106.6,-44.1 -58.8,-58.8 -58.8,-154.4 0,-213.1 28.5,-28.5 66.3,-44.1 106.6,-44.1s78.1,15.7 106.6,44.1c58.8,58.8 58.8,154.4 0,213.1 -28.5,28.5 -66.3,44.1 -106.6,44.1zM736,612.3c-34.9,0 -67.7,13.6 -92.4,38.3 -51,51 -51,133.9 0,184.9 24.7,24.7 57.5,38.3 92.4,38.3s67.7,-13.6 92.4,-38.3c51,-51 51,-133.9 0,-184.9 -24.7,-24.7 -57.5,-38.3 -92.4,-38.3z"
android:fillColor="#333333"/>
<path
android:pathData="M778.8,659.2m20.5,20.5l0,0q20.5,20.5 0,41l-85.7,85.7q-20.5,20.5 -41,0l0,0q-20.5,-20.5 0,-41l85.7,-85.7q20.5,-20.5 41,0Z"
android:fillColor="#FFEBA4"/>
<path
android:pathData="M693.2,824.8c-10,0 -20,-3.8 -27.6,-11.4 -15.2,-15.2 -15.2,-39.9 0,-55.1l85.7,-85.7c15.2,-15.2 39.9,-15.2 55.1,0 15.2,15.2 15.2,39.9 0,55.1l-85.7,85.7c-7.6,7.6 -17.6,11.4 -27.6,11.4zM778.8,681.2c-5.1,0 -9.8,2 -13.4,5.6l-85.7,85.7c-7.4,7.4 -7.4,19.5 0,26.9s19.5,7.4 26.9,0l85.7,-85.7c7.4,-7.4 7.4,-19.5 0,-26.9a18.9,18.9 0,0 0,-13.4 -5.6z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M856,509.9c0,236.8 -62,300.1 -298.8,300.1S259.7,746.6 259.7,509.9s60.8,-298.8 297.5,-298.8S856,273.1 856,509.9z"
android:fillColor="#FEC773"/>
<path
android:pathData="M303.5,509.9c0,-229.3 57,-294.7 275.6,-298.6 -7.1,-0.1 -14.4,-0.2 -21.9,-0.2 -236.8,0 -297.5,62 -297.5,298.8s60.8,300.1 297.5,300.1c7.5,0 14.8,-0.1 21.9,-0.2 -218.6,-4 -275.6,-70.6 -275.6,-299.9z"
android:fillColor="#F29816"/>
<path
android:pathData="M557.2,819.9c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10c61.5,0 107.3,-4.2 144.2,-13.3 37.6,-9.3 66.1,-24 86.9,-45 20.8,-21 35.4,-49.6 44.6,-87.4C841.8,617.4 846,571.5 846,509.9s-4.2,-107.4 -13.1,-144.2c-9.2,-37.6 -23.7,-66.1 -44.6,-86.9 -20.8,-20.8 -49.3,-35.4 -86.9,-44.6 -36.8,-8.9 -82.6,-13.1 -144.2,-13.1 -52.4,0 -94.2,3.1 -127.8,9.6 -35,6.7 -62.3,17.2 -83.7,32.2 -41.9,29.3 -64.2,78.4 -72.3,159.5 -0.6,5.5 -5.4,9.5 -10.9,9 -5.5,-0.6 -9.5,-5.4 -9,-10.9 8.7,-87.4 33.6,-141 80.7,-173.9 45.5,-31.8 112.2,-45.3 222.9,-45.3 242.4,0 308.8,66.4 308.8,308.8 0,63.3 -4.3,110.7 -13.7,149.1 -10.1,41.4 -26.4,73.1 -49.8,96.7 -23.5,23.7 -55,40.2 -96.3,50.3 -38.5,9.5 -85.8,13.9 -149,13.9z"
android:fillColor="#333333"/>
<path
android:pathData="M208.7,808.8c-5.4,-7.2 -4.4,-17.4 2.3,-23.4l129.4,-117.8c15.2,-13.8 39,-11.5 51.2,4.9 12.3,16.5 7.7,39.9 -9.9,50.5l-149.9,90.3c-7.7,4.7 -17.7,2.7 -23.1,-4.5z"
android:fillColor="#FE4933"/>
<path
android:pathData="M410.6,832c4.9,6.6 13.8,8.6 21.1,4.8l142.1,-75.1c25,-13.2 30.7,-46.5 11.6,-67.3l-54.2,-58.9c-5.2,-5.7 -5.7,-14.2 -1.2,-20.5l30,-41c4.9,-6.8 14.4,-8.2 21.1,-3.2l44.9,33.7c8.8,6.6 20.2,8.8 30.9,5.9l95.8,-25.9c8.8,-2.4 14.4,-11 13.1,-20 -1.4,-8.9 -9.2,-15.5 -18.2,-15.3l-79.8,2.2c-4.4,0.1 -8.8,-1.4 -12.1,-4.3l-43,-36.5a88.2,88.2 0,0 1,-12.8 -13.4l-47.2,-61.2a45.5,45.5 0,0 0,-17.4 -13.7l-64,-28.7a59.1,59.1 0,0 0,-35.8 -4l-111.3,22.3c-8.5,1.7 -14.3,9.6 -13.3,18.3 1,8.4 8.1,14.8 16.6,14.8h109.6c3.8,0 7.5,0.9 10.8,2.6l35.4,18.2c9,4.6 11.9,16.1 6.2,24.5l-58.6,85.8c-17.9,26.2 -14.3,61.5 8.5,83.5l62.8,60.8c6.7,6.4 6,17.3 -1.4,22.9l-86.8,65.4c-7.3,5.5 -8.8,15.9 -3.3,23.2z"
android:fillColor="#FE4933"/>
<path
android:pathData="M663.4,402m-64,0a64,64 0,1 0,128 0,64 64,0 1,0 -128,0Z"
android:fillColor="#FE4933"/>
<path
android:pathData="M240,585.7m21.5,0l64.5,0q21.5,0 21.5,21.5l0,0q0,21.5 -21.5,21.5l-64.5,0q-21.5,0 -21.5,-21.5l0,0q0,-21.5 21.5,-21.5Z"
android:fillColor="#FE4933"/>
<path
android:pathData="M165.5,483m30.5,0l123.3,0q30.5,0 30.5,30.5l0,0q0,30.5 -30.5,30.5l-123.3,0q-30.5,0 -30.5,-30.5l0,0q0,-30.5 30.5,-30.5Z"
android:fillColor="#FE4933"/>
<path
android:pathData="M222.7,825.9c-8.4,0 -16.7,-3.9 -22,-11.1a27.4,27.4 0,0 1,3.5 -36.8L333.6,660.2c9.3,-8.5 21.9,-12.7 34.4,-11.4 12.5,1.2 24.1,7.7 31.6,17.8s10.5,23 8,35.4a44.8,44.8 0,0 1,-20.8 29.7l-149.9,90.3a27.5,27.5 0,0 1,-14.2 4zM363.6,668.5c-6.2,0 -12,2.3 -16.6,6.4L217.7,792.8a7.5,7.5 0,0 0,-1 10.1,7.5 7.5,0 0,0 9.9,2l149.9,-90.3c6.1,-3.7 10.1,-9.5 11.5,-16.4 1.4,-6.9 -0.2,-13.9 -4.4,-19.5s-10.4,-9.2 -17.5,-9.8c-0.8,-0.1 -1.6,-0.1 -2.5,-0.1z"
android:fillColor="#333333"/>
<path
android:pathData="M423.9,848.7c-8.1,0 -16.1,-3.8 -21.3,-10.7 -8.7,-11.7 -6.3,-28.4 5.3,-37.2l86.8,-65.4a5,5 0,0 0,2 -3.7c0.1,-0.9 -0.1,-2.5 -1.5,-4l-62.8,-60.8a74.9,74.9 0,0 1,-9.8 -96.3l58.6,-85.8a6.7,6.7 0,0 0,1 -5.5c-0.3,-1.1 -1.1,-3.2 -3.5,-4.4l-35.4,-18.2c-1.9,-1 -4.1,-1.5 -6.2,-1.5L327.5,455c-13.6,0 -25,-10.2 -26.5,-23.7 -1.6,-13.9 7.6,-26.5 21.3,-29.2l111.3,-22.3c14.2,-2.8 28.6,-1.2 41.8,4.7l64,28.7a55.6,55.6 0,0 1,21.2 16.7l47.2,61.2c3.4,4.3 7.2,8.4 11.4,11.9l43,36.5a8,8 0,0 0,5.4 1.9l79.8,-2.2c14.1,-0.4 26.3,9.8 28.4,23.8 2.1,14 -6.6,27.4 -20.3,31.1l-95.8,25.9c-13.7,3.7 -28.1,0.9 -39.5,-7.6l-44.9,-33.7a5,5 0,0 0,-3.8 -0.9c-0.8,0.1 -2.2,0.5 -3.3,2l-30,41a6.2,6.2 0,0 0,0.4 7.8l54.2,58.9c11.2,12.2 16.1,28.6 13.2,44.9 -2.8,16.4 -12.8,30.2 -27.5,37.9L436.4,845.6c-4,2.1 -8.3,3.1 -12.5,3.1zM418.7,826a6.6,6.6 0,0 0,8.4 1.9l142.1,-75.1c9.1,-4.8 15.4,-13.4 17.1,-23.6 1.8,-10.2 -1.3,-20.4 -8.3,-28l-54.2,-58.9c-8.4,-9.1 -9.2,-23.1 -1.9,-33.1l30,-41c4,-5.4 9.8,-9 16.5,-10 6.7,-1 13.3,0.7 18.7,4.7l44.9,33.7c6.4,4.8 14.5,6.4 22.2,4.3l95.8,-25.9a7.9,7.9 0,0 0,5.8 -8.8c-0.6,-4 -4.1,-6.8 -8.1,-6.7l-79.8,2.2c-6.9,0.2 -13.6,-2.2 -18.9,-6.6l-43,-36.5a99.1,99.1 0,0 1,-14.3 -15l-47.2,-61.2a35.5,35.5 0,0 0,-13.6 -10.7l-64,-28.7c-9.4,-4.2 -19.6,-5.4 -29.7,-3.3l-111.3,22.3a6.7,6.7 0,0 0,-5.3 7.3,6.7 6.7,0 0,0 6.7,5.9h109.6c5.3,0 10.7,1.3 15.4,3.7l35.4,18.2a26.9,26.9 0,0 1,13.7 17.3c1.9,7.4 0.5,15.4 -3.9,21.7l-58.6,85.8a55,55 0,0 0,7.2 70.7l62.8,60.8c5.3,5.1 8,12.2 7.6,19.6s-4.1,14.1 -9.9,18.5l-86.8,65.4c-2.9,2.2 -3.5,6.3 -1.3,9.3z"
android:fillColor="#333333"/>
<path
android:pathData="M663.4,476c-40.8,0 -74,-33.2 -74,-74s33.2,-74 74,-74 74,33.2 74,74 -33.2,74 -74,74zM663.4,348c-29.8,0 -54,24.2 -54,54s24.2,54 54,54 54,-24.2 54,-54 -24.2,-54 -54,-54zM326,638.7h-64.5c-17.4,0 -31.5,-14.1 -31.5,-31.5s14.1,-31.5 31.5,-31.5h64.5c17.4,0 31.5,14.1 31.5,31.5s-14.1,31.5 -31.5,31.5zM261.5,595.7c-6.3,0 -11.5,5.2 -11.5,11.5s5.2,11.5 11.5,11.5h64.5c6.3,0 11.5,-5.2 11.5,-11.5s-5.2,-11.5 -11.5,-11.5h-64.5zM319.3,554L196,554c-22.3,0 -40.5,-18.2 -40.5,-40.5s18.2,-40.5 40.5,-40.5h123.3c22.3,0 40.5,18.2 40.5,40.5s-18.2,40.5 -40.5,40.5zM196,493c-11.3,0 -20.5,9.2 -20.5,20.5s9.2,20.5 20.5,20.5h123.3c11.3,0 20.5,-9.2 20.5,-20.5s-9.2,-20.5 -20.5,-20.5L196,493z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M188.9,170m82.3,0l327.5,0q82.3,0 82.3,82.3l0,514.4q0,82.3 -82.3,82.3l-327.5,0q-82.3,0 -82.3,-82.3l0,-514.4q0,-82.3 82.3,-82.3Z"
android:fillColor="#35A5F6"/>
<path
android:pathData="M598.7,859H271.2c-50.9,0 -92.3,-41.4 -92.3,-92.3V252.3c0,-50.9 41.4,-92.3 92.3,-92.3H598.7c50.9,0 92.3,41.4 92.3,92.3v327.6c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V252.3c0,-39.9 -32.4,-72.3 -72.3,-72.3H271.2c-39.9,0 -72.3,32.4 -72.3,72.3v514.4c0,39.9 32.4,72.3 72.3,72.3H598.7c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M237.2,217.7m38.2,0l319.1,0q38.2,0 38.2,38.2l0,433q0,38.2 -38.2,38.2l-319.1,0q-38.2,0 -38.2,-38.2l0,-433q0,-38.2 38.2,-38.2Z"
android:fillColor="#DCF1FC"/>
<path
android:pathData="M591.5,737H272.4c-26.5,0 -48.2,-21.6 -48.2,-48.2v-433c0,-26.5 21.6,-48.2 48.2,-48.2H591.5c26.5,0 48.2,21.6 48.2,48.2v300.1c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V255.9c0,-15.5 -12.6,-28.1 -28.1,-28.1H272.4c-15.5,0 -28.1,12.6 -28.1,28.1v433c0,15.5 12.6,28.1 28.1,28.1H591.5c15.5,0 28.1,-12.6 28.1,-28.1v-54.7c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v54.7c0,26.5 -21.6,48.2 -48.2,48.2z"
android:fillColor="#333333"/>
<path
android:pathData="M354.4,760m24.5,0l112,0q24.5,0 24.5,24.5l0,0q0,24.5 -24.5,24.5l-112,0q-24.5,0 -24.5,-24.5l0,0q0,-24.5 24.5,-24.5Z"
android:fillColor="#DCF1FC"/>
<path
android:pathData="M337.5,469.4c-2.4,-2.3 -3.6,-5.7 -3.6,-10.2v-1.2c0,-4.5 1.2,-7.9 3.5,-10.1 2.3,-2.3 6,-3.8 10.9,-4.6 6.1,-1 10.9,-3 14.6,-6.3 3.6,-3.2 5.4,-7.1 5.4,-11.6 0,-4 -0.8,-7.5 -2.4,-10.4 -1.6,-2.9 -4,-5.1 -7.1,-6.6 -3.1,-1.5 -6.9,-2.3 -11.2,-2.3 -2.9,0 -5.5,0.3 -7.7,0.8 -2.3,0.6 -4.3,1.4 -6,2.5l-4.3,3.4c-2.7,2.3 -5.2,3.9 -7.3,5.1 -2.2,1.1 -4.8,1.7 -7.8,1.7h-1.2c-6.1,0 -10.5,-1.8 -13.2,-5.3 -2.7,-3.5 -2.7,-7.8 0.2,-12.8 3,-5.1 6.9,-9.7 11.7,-13.7 4.7,-4 10.1,-7.2 16.3,-9.5 6.1,-2.3 12.6,-3.5 19.5,-3.5 9.3,0 18,2.1 26.2,6.4s14.7,10.1 19.5,17.5c4.8,7.4 7.2,15.5 7.2,24.3 0,8.2 -2.8,15.5 -8.3,22 -5.5,6.5 -13,11.7 -22.5,15.5l-0.2,-6c13,3.2 23,8.7 30.1,16.5 7.1,7.8 10.6,17.9 10.6,30.5 0,10.1 -2.8,19.5 -8.4,28.3 -5.6,8.8 -13.1,15.7 -22.5,20.9 -9.4,5.2 -19.4,7.8 -30,7.8 -8.7,0 -17,-1.7 -24.9,-5.2s-14.9,-8.2 -20.8,-14.3c-5.9,-6.1 -10.2,-12.9 -12.8,-20.5 -1.8,-5 -1.3,-9 1.3,-12 2.7,-3 6.6,-4.6 11.9,-4.6h2.4c4.2,0 7.3,1 9.5,2.9 2.2,1.9 4.6,5.3 7.3,10.1 1.6,2.6 3.7,4.8 6.3,6.6 2.6,1.9 5.5,3.3 8.8,4.2 3.3,1 6.9,1.4 10.9,1.4 5.6,0 10.6,-1.1 14.9,-3.3s7.7,-5.2 10.1,-9.1c2.4,-3.9 3.6,-8.4 3.6,-13.4 0,-7.9 -2.5,-14.2 -7.5,-19 -5,-4.8 -12.3,-7.8 -21.9,-8.9 -5,-0.5 -8.7,-1.9 -11.1,-4.2zM478.1,546.2c-13.7,-8.3 -24.5,-19.4 -32.3,-33.5 -7.8,-14 -11.7,-29.4 -11.7,-46.1s3.9,-31.8 11.7,-45.8c7.8,-14 18.5,-25.2 32.3,-33.5 13.7,-8.3 28.9,-12.4 45.6,-12.4 11.7,0 22.5,2.1 32.5,6.3 9.9,4.2 19,10.1 27.2,17.8 3.8,3.7 5.6,7.4 5.3,11.2 -0.3,3.8 -2.6,7.3 -6.7,10.7l-0.7,0.5c-3.8,3 -7.5,4.4 -11.1,4.1 -3.5,-0.3 -7.2,-2.3 -11.1,-5.8 -5.1,-4.8 -10.5,-8.4 -16.1,-10.7 -5.6,-2.3 -12,-3.5 -19.3,-3.5 -11.4,0 -21.5,2.6 -30.2,7.8 -8.8,5.2 -15.6,12.5 -20.5,21.8 -4.9,9.3 -7.3,19.8 -7.3,31.5s2.4,22.5 7.2,31.8c4.8,9.3 11.6,16.6 20.5,21.8 8.8,5.2 18.9,7.8 30.3,7.8v30.6c-16.7,0 -31.9,-4.1 -45.6,-12.4zM570.3,508.9c3.5,-0.4 7.1,0.8 10.9,3.7l0.7,0.5c4.3,3.2 6.7,6.8 7.1,10.7 0.4,3.9 -1.3,7.7 -5.2,11.2 -8,7.2 -17.2,13 -27.4,17.2s-21.2,6.4 -32.7,6.4c-16.7,0 -31.9,-4.1 -45.6,-12.4 -13.7,-8.3 -24.5,-19.4 -32.3,-33.5 -7.8,-14 -11.7,-29.4 -11.7,-46.1s3.9,-31.8 11.7,-45.8c7.8,-14 18.5,-25.2 32.3,-33.5 13.7,-8.3 28.9,-12.4 45.6,-12.4v30.6c-11.4,0 -21.5,2.6 -30.2,7.8 -8.8,5.2 -15.6,12.5 -20.5,21.8 -4.9,9.3 -7.3,19.8 -7.3,31.5s2.4,22.5 7.2,31.8c4.8,9.3 11.6,16.6 20.5,21.8 8.8,5.2 18.9,7.8 30.3,7.8 7.1,0 13.5,-1.2 19.4,-3.5 5.9,-2.3 11.3,-5.7 16.3,-10 3.8,-3.4 7.5,-5.3 10.9,-5.7z"
android:fillColor="#0080E0"/>
<path
android:pathData="M701.3,683c0,-33.8 -30.7,-61.3 -68.5,-61.3s-68.5,27.4 -68.5,61.3 30.7,61.3 68.5,61.3c6.6,0 12.9,-0.8 18.9,-2.4v117.3c0,13.7 11.1,24.8 24.8,24.8 13.7,0 24.8,-11.1 24.8,-24.8V688c0,-0.7 -0,-1.3 -0.1,-2 0.1,-1 0.1,-2 0.1,-3zM811.2,556c-37.8,0 -68.5,27.4 -68.5,61.3 0,1 0,2 0.1,3 -0.1,0.6 -0.1,1.3 -0.1,2v171.2c0,13.7 11.1,24.8 24.8,24.8 13.7,0 24.8,-11.1 24.8,-24.8V676.2a76.2,76.2 0,0 0,18.9 2.4c37.8,0 68.5,-27.4 68.5,-61.3S849,556 811.2,556z"
android:fillColor="#FEDC5A"/>
<path
android:pathData="M626,632s-28,16 -29,45c0,0 -5,43 42,57l-6.2,7.5s-68.7,1.1 -68.2,-63.7c0,0 13.4,-54.8 57.4,-51.8l4,6z"
android:fillColor="#F29816"/>
<path
android:pathData="M676.5,894c-19.2,0 -34.8,-15.6 -34.8,-34.8L641.7,756.9c0,-1 -0.5,-1.7 -0.9,-2 -0.3,-0.3 -1.1,-0.8 -2.2,-0.8 -1.9,0.1 -3.9,0.2 -5.9,0.2 -43.3,0 -78.5,-32 -78.5,-71.3s35.2,-71.3 78.5,-71.3 78.5,32 78.5,71.3c0,0.9 -0,1.9 -0.1,2.9 0.1,0.7 0.1,1.4 0.1,2.1v171.2c0,19.2 -15.6,34.8 -34.8,34.8zM638.8,734.1c5.8,0 11.4,2.2 15.6,6.2 4.6,4.3 7.2,10.4 7.2,16.7v102.3c0,8.1 6.6,14.8 14.8,14.8s14.8,-6.6 14.8,-14.8L691.3,688c0,-0.3 -0,-0.7 -0.1,-1.2 -0,-0.4 -0,-0.9 -0,-1.3 0.1,-0.9 0.1,-1.7 0.1,-2.5 0,-28.3 -26.2,-51.3 -58.5,-51.3s-58.5,23 -58.5,51.3 26.2,51.3 58.5,51.3c1.5,0 3,-0.1 4.5,-0.2 0.5,-0 1,-0.1 1.5,-0.1z"
android:fillColor="#333333"/>
<path
android:pathData="M811.2,564.5S770,577 769,605v213.2s-24.1,1.4 -25.6,-18.9V606.8s12,-48.7 67.8,-42.3z"
android:fillColor="#F29816"/>
<path
android:pathData="M767.5,828.2c-19.2,0 -34.8,-15.6 -34.8,-34.8V622.2c0,-0.7 0,-1.3 0.1,-2.1 -0.1,-1 -0.1,-2 -0.1,-2.9 0,-39.3 35.2,-71.3 78.5,-71.3s78.5,32 78.5,71.3 -35.2,71.3 -78.5,71.3c-2.4,0 -4.9,-0.1 -7.3,-0.3 -0.6,-0.1 -1,0.2 -1.2,0.4 -0.4,0.4 -0.4,0.8 -0.4,0.9v103.9c0,19.2 -15.6,34.8 -34.8,34.8zM811.2,566c-32.3,0 -58.5,23 -58.5,51.3 0,0.8 0,1.6 0.1,2.5 0,0.4 0,0.9 -0,1.3 -0,0.5 -0.1,0.9 -0.1,1.2v171.2c0,8.1 6.6,14.8 14.8,14.8s14.8,-6.6 14.8,-14.8V689.5c0,-5.9 2.5,-11.6 6.9,-15.6 4.4,-4.1 10.4,-6.1 16.4,-5.6 1.9,0.2 3.8,0.2 5.6,0.2 32.3,0 58.5,-23 58.5,-51.3s-26.2,-51.3 -58.5,-51.3z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,75 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M679.2,668.4m19.8,2.6l77,10q19.8,2.6 17.2,22.3l-10,77q-2.6,19.8 -22.3,17.2l-77,-10q-19.8,-2.6 -17.2,-22.3l10,-77q2.6,-19.8 22.3,-17.2Z"
android:fillColor="#B1DCFD"/>
<path
android:pathData="M704,679l-8.5,63.4s-3,32.8 13.5,33.6l72,8 -2.2,6.6 -22.7,7.4L664,789l12.1,-97 14.4,-14.3L704,679z"
android:fillColor="#89CBF4"/>
<path
android:pathData="M763.4,807.6c-1.3,0 -2.6,-0.1 -3.9,-0.3l-77,-10c-5.5,-0.7 -9.3,-5.7 -8.6,-11.2 0.7,-5.5 5.7,-9.3 11.2,-8.6l77,10c2.6,0.3 5.2,-0.4 7.3,-2a9.8,9.8 0,0 0,3.8 -6.6l10,-77c0.3,-2.6 -0.4,-5.2 -2,-7.3a9.8,9.8 0,0 0,-6.6 -3.8l-77,-10c-2.6,-0.3 -5.2,0.4 -7.3,2s-3.4,4 -3.8,6.6l-2.4,18.7c-0.7,5.5 -5.7,9.3 -11.2,8.6 -5.5,-0.7 -9.3,-5.7 -8.6,-11.2l2.4,-18.7c1,-7.9 5.1,-15 11.4,-19.9 6.3,-4.9 14.2,-7 22.1,-6l77,10c7.9,1 15,5.1 19.9,11.4 4.9,6.3 7,14.2 6,22.1l-10,77c-1,7.9 -5.1,15 -11.4,19.9 -5.3,4.1 -11.6,6.2 -18.2,6.2z"
android:fillColor="#333333"/>
<path
android:pathData="M277.6,467.3l31.5,353.6c1.4,15.9 14.7,28.1 30.7,28.1h250.1c15.9,0 29.3,-12.2 30.7,-28.1l27.6,-309.8 3.5,-46.5 -374.1,2.6z"
android:fillColor="#FFD9D9"/>
<path
android:pathData="M662.6,407.5H268.8c0,-108.7 88.1,-196.9 196.9,-196.9s196.9,88.1 196.9,196.9z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M612.2,175.8l-44.5,-12.5c-4.3,-1.2 -8.8,1.2 -10.1,5.5l-16.4,53.8a196.9,196.9 0,0 1,56.5 35.5l20.3,-72.2a8.3,8.3 0,0 0,-5.7 -10.2z"
android:fillColor="#FE972B"/>
<path
android:pathData="M597.6,268.2c-0.9,0 -1.8,-0.1 -2.7,-0.4 -5.3,-1.5 -8.4,-7 -6.9,-12.3l19.8,-70.5 -41.2,-11.6 -6.1,20c-1.6,5.3 -7.2,8.3 -12.5,6.6 -5.3,-1.6 -8.3,-7.2 -6.6,-12.5l6.6,-21.6c2.9,-9.4 12.9,-14.9 22.4,-12.3l44.5,12.5c9.7,2.7 15.4,12.8 12.6,22.5l-20.3,72.2c-1.2,4.4 -5.3,7.3 -9.6,7.3z"
android:fillColor="#333333"/>
<path
android:pathData="M450,592.9c-56,21.5 -117.5,18.1 -159.3,11.4l19.3,216.1c1.4,16.2 15,28.6 31.3,28.6h248.9c16.3,0 29.9,-12.4 31.3,-28.6l21.8,-245c-95.2,-23.2 -193.4,17.6 -193.4,17.6z"
android:fillColor="#F76C69"/>
<path
android:pathData="M327.3,608.8l16.8,185.4s0,19.4 15.9,19.4h225.2s25.6,1.8 32.7,-15l-1.8,31.8 -18.5,15.9H333.8l-22.1,-17.8 -19.8,-222.3 35.4,2.5z"
android:fillColor="#CE4141"/>
<path
android:pathData="M465.9,217.4s-128.8,34.6 -137.2,167.1h-59.9s10.6,-164.6 197.1,-167.1z"
android:fillColor="#F29816"/>
<path
android:pathData="M662.8,417.5L269,417.5c-5.5,0 -10,-4.5 -10,-10 0,-114.1 92.8,-206.9 206.9,-206.9s206.9,92.8 206.9,206.9c0,5.5 -4.5,10 -10,10zM279.3,397.5h373.2c-5.2,-98.4 -86.9,-176.9 -186.6,-176.9s-181.4,78.5 -186.6,176.9z"
android:fillColor="#333333"/>
<path
android:pathData="M239.2,384.5m21.6,0l409.9,0q21.6,0 21.6,21.6l0,35.5q0,21.6 -21.6,21.6l-409.9,0q-21.6,0 -21.6,-21.6l0,-35.5q0,-21.6 21.6,-21.6Z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M308.8,389.8s-16.9,1.7 -16.9,18.5v36.2s0.1,13.2 16.9,13.2h-65.6v-67.9h65.6z"
android:fillColor="#F29816"/>
<path
android:pathData="M313.7,465.1l12.3,137.1h-29.8l-11.1,-137.5 28.6,0.4z"
android:fillColor="#FFC7C7"/>
<path
android:pathData="M352.9,619.4c-23.6,0 -45.5,-2.3 -63.8,-5.3 -5.4,-0.9 -9.2,-6 -8.3,-11.5 0.9,-5.4 6,-9.2 11.5,-8.3 40.5,6.5 100.1,9.9 154,-10.8 2.3,-0.9 26.7,-10.8 62.7,-18 34.2,-6.8 85.8,-12.4 136.7,0 5.4,1.3 8.6,6.7 7.3,12.1 -1.3,5.4 -6.7,8.6 -12.1,7.3 -90.9,-22.2 -186.2,16.7 -187.1,17.1 -0.1,0 -0.2,0.1 -0.3,0.1 -33.4,12.9 -68.6,17.1 -100.7,17.1z"
android:fillColor="#333333"/>
<path
android:pathData="M590.8,859H340.7c-21.3,0 -38.7,-16 -40.6,-37.2l-31.5,-353.6c-0.5,-5.5 3.6,-10.4 9.1,-10.9 5.5,-0.5 10.4,3.6 10.9,9.1l31.5,353.6c1,10.8 9.9,19 20.7,19h250.1c10.8,0 19.8,-8.1 20.7,-19l27.6,-309.8c0.5,-5.5 5.3,-9.6 10.9,-9.1 5.5,0.5 9.6,5.3 9.1,10.9l-27.6,309.8c-1.9,21.2 -19.4,37.2 -40.6,37.2z"
android:fillColor="#333333"/>
<path
android:pathData="M673.9,473.1H259c-16,0 -29,-13 -29,-29v-40.5c0,-16 13,-29 29,-29h82.1c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-82.1c-5,0 -9,4.1 -9,9v40.5c0,5 4.1,9 9,9h414.9c5,0 9,-4.1 9,-9v-40.5c0,-5 -4.1,-9 -9,-9H419.2c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h254.7c16,0 29,13 29,29v40.5c0,16 -13,29 -29,29z"
android:fillColor="#333333"/>
<path
android:pathData="M738.3,724.8m17.7,9.2l68.8,35.9q17.7,9.2 8.4,26.9l-35.9,68.8q-9.2,17.7 -26.9,8.4l-68.8,-35.9q-17.7,-9.2 -8.4,-26.9l35.9,-68.8q9.2,-17.7 26.9,-8.4Z"
android:fillColor="#B1DCFD"/>
<path
android:pathData="M755,740l-27,56s-9,16 6,23l69.2,35.4L787.1,872l-23.8,-1.7L684,828l45,-86 18.7,-7.8L755,740z"
android:fillColor="#89CBF4"/>
<path
android:pathData="M779.7,886.3c-4.7,0 -9.4,-1.1 -13.8,-3.4L697.1,847c-4.9,-2.6 -6.8,-8.6 -4.2,-13.5 2.6,-4.9 8.6,-6.8 13.5,-4.2l68.8,35.9c4.8,2.5 10.9,0.6 13.4,-4.2l35.9,-68.8a9.8,9.8 0,0 0,0.7 -7.6,9.8 9.8,0 0,0 -4.9,-5.8l-68.8,-35.9a9.8,9.8 0,0 0,-7.6 -0.7,9.8 9.8,0 0,0 -5.8,4.9c-2.6,4.9 -8.6,6.8 -13.5,4.2 -4.9,-2.6 -6.8,-8.6 -4.2,-13.5 3.7,-7.1 9.9,-12.3 17.6,-14.7 7.6,-2.4 15.7,-1.7 22.8,2l68.8,35.9c7.1,3.7 12.3,9.9 14.7,17.6 2.4,7.6 1.7,15.7 -2,22.8l-35.9,68.8c-5.3,10.2 -15.8,16.1 -26.6,16.1z"
android:fillColor="#333333"/>
<path
android:pathData="M582,768.8m19.5,-3.9l76.1,-15.3q19.5,-3.9 23.5,15.6l15.3,76.1q3.9,19.5 -15.6,23.5l-76.1,15.3q-19.5,3.9 -23.5,-15.6l-15.3,-76.1q-3.9,-19.5 15.6,-23.5Z"
android:fillColor="#B1DCFD"/>
<path
android:pathData="M607.2,774.2l12.7,60.9s2.6,18.2 18.8,14.6l76.4,-14.1 -2.1,23.8 -19.9,13.1 -88.6,14.8 -16.7,-95.6 10.1,-17.6 9.3,0.2z"
android:fillColor="#89CBF4"/>
<path
android:pathData="M620.8,890.4c-5.8,0 -11.5,-1.7 -16.5,-5 -6.7,-4.4 -11.2,-11.2 -12.8,-19l-15.3,-76.1c-1.6,-7.8 0,-15.8 4.4,-22.5 4.4,-6.7 11.2,-11.2 19,-12.8l76.1,-15.3c16.2,-3.3 32,7.3 35.2,23.4l15.3,76.1c1.6,7.8 0,15.8 -4.4,22.5 -4.4,6.7 -11.2,11.2 -19,12.8s-76.1,15.3 -76.1,15.3c-2,0.4 -4,0.6 -6,0.6zM681.6,759.2c-0.6,0 -1.3,0.1 -2,0.2l-76.1,15.3a9.9,9.9 0,0 0,-6.3 4.2,9.8 9.8,0 0,0 -1.5,7.4l15.3,76.1a9.9,9.9 0,0 0,4.2 6.3,9.8 9.8,0 0,0 7.4,1.5l76.1,-15.3a9.9,9.9 0,0 0,6.3 -4.2,9.8 9.8,0 0,0 1.5,-7.4l-15.3,-76.1c-0.9,-4.7 -5.1,-8 -9.7,-8z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,51 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M525,192.6l-23.7,41.1 -23.7,-41c-74.9,11.9 -106.7,81.7 -92.7,188 15.8,120.1 70.3,148.9 116.6,148.9s100.5,-32.6 116.1,-148.9c14.2,-106.4 -17.4,-176.3 -92.6,-188z"
android:fillColor="#F76C69"/>
<path
android:pathData="M183.3,395.9L215,431.1l-46.3,9.9c-11.9,74.9 44.7,126.7 150.1,146.2 119.1,22 163.3,-20.8 177.6,-64.8 14.6,-45 0,-105.7 -105.8,-156.4 -96.8,-46.4 -173.1,-37.9 -207.4,29.9z"
android:fillColor="#F76C69"/>
<path
android:pathData="M819.2,395.9l-31.7,35.3 46.3,9.9c11.9,74.9 -44.7,126.7 -150.1,146.2 -119.1,22 -163.3,-20.8 -177.6,-64.8 -14.6,-45 -0,-105.7 105.8,-156.4 3.5,-1.7 6.9,-3.3 10.3,-4.8 91.9,-41 164,-30.7 197.1,34.7z"
android:fillColor="#F76C69"/>
<path
android:pathData="M284.5,781.3l43.3,-19.3 -4.9,47.1c67.6,34.4 134.3,-3.3 185.5,-97.6 57.8,-106.4 30.7,-161.8 -6.8,-189 -38.3,-27.8 -100.5,-32.7 -181.4,52.2 -74.1,77.8 -89.6,152.9 -35.6,206.5z"
android:fillColor="#F76C69"/>
<path
android:pathData="M679.9,809.3l-5,-47.2 43.3,19.3c53.6,-53.6 38.3,-128.8 -35.5,-206.5 -83.4,-87.8 -144.4,-79.2 -181.8,-52 -38.3,27.8 -62.2,85.5 -6.4,188.7 51,94.5 117.7,132.4 185.4,97.7z"
android:fillColor="#F76C69"/>
<path
android:pathData="M692,346s-32.5,149.7 -119.7,159.4c0,0 51.7,-87.5 53.2,-138.9 0,0 38.5,-22.4 66.5,-20.4zM731.9,646s-146.6,12.2 -182.7,-67.8c0,0 99.2,22.1 148.6,7.7 0,0 27.4,32.8 34.1,60.1zM463.5,779s-63.8,-142.8 1.1,-201.9c0,0 9.6,101.2 38.6,143.7 0,0 -15.9,43.4 -39.8,58.2zM250.1,565.3S364,457.2 440.3,500.7c0,0 -93.3,40.4 -124.7,81.1 0,0 -44,1.6 -65.5,-16.5zM388.2,290.1s131.9,76 114.1,161.9c0,0 -67.3,-76.2 -115.7,-93.6 0,0 -8.9,-42.4 1.6,-68.4z"
android:fillColor="#E54E4E"/>
<path
android:pathData="M387.4,371c-5.2,0 -9.5,-4 -10,-9.2 -3.8,-46.1 1.5,-84.7 15.8,-114.5 15,-31.4 39.1,-51.9 71.6,-61.2 12.8,-3.6 26.3,1.8 32.8,13.2l16.9,29.2c2.8,4.8 1.1,10.9 -3.7,13.7s-10.9,1.1 -13.7,-3.7l-16.9,-29.2c-2,-3.5 -6.1,-5.1 -10.1,-4 -26.8,7.6 -46.6,24.6 -59,50.5 -12.7,26.6 -17.4,61.7 -13.9,104.2 0.4,5.5 -3.7,10.3 -9.1,10.8 -0.3,0 -0.6,0 -0.8,0zM576,508.7a10,10 0,0 1,-6.8 -2.7,10 10,0 0,1 -0.5,-14.1c22,-23.6 36.7,-61.5 43.5,-112.6 6.8,-50.8 2.7,-93.7 -11.9,-123.9 -14.4,-29.9 -38.7,-47.7 -72.3,-52.9 -5.5,-0.9 -9.2,-6 -8.3,-11.4 0.9,-5.5 6,-9.2 11.4,-8.3 79.4,12.4 116.2,85 100.9,199.2 -7.4,55.2 -23.8,96.8 -48.7,123.6a10,10 0,0 1,-7.3 3.2zM309,594.3c-0.7,0 -1.5,-0.1 -2.2,-0.2 -46.7,-10.4 -82.9,-27.4 -107.8,-50.4 -26.1,-24.2 -38.7,-54 -37.3,-88.6 0.5,-13 9.9,-24 22.7,-26.7l33,-7c5.4,-1.1 10.7,2.3 11.9,7.7 1.1,5.4 -2.3,10.7 -7.7,11.9l-33,7c-3.9,0.8 -6.7,4.1 -6.9,8 -1.2,28.4 9.2,53 30.9,73.1 22.2,20.6 55.4,35.9 98.5,45.5 5.4,1.2 8.8,6.6 7.6,11.9a10,10 0,0 1,-9.8 7.8z"
android:fillColor="#333333"/>
<path
android:pathData="M497,463.6c-3.8,0 -7.4,-2.2 -9.1,-5.8 -14.2,-30.9 -46.8,-58.8 -97,-82.8 -46.2,-22.2 -88.2,-31.5 -121.5,-27 -32.9,4.5 -57.3,22.1 -72.7,52.4 -2.5,4.9 -8.5,6.9 -13.4,4.4s-6.9,-8.5 -4.4,-13.4c36.3,-71.7 116.7,-84.3 220.7,-34.4 54.5,26.1 90.3,57.3 106.5,92.5 2.3,5 0.1,11 -4.9,13.3 -1.4,0.6 -2.8,0.9 -4.2,0.9zM629.2,603.2c-30.8,0 -56.8,-5.6 -77.6,-16.8 -4.9,-2.6 -6.7,-8.7 -4.1,-13.5 2.6,-4.9 8.7,-6.7 13.5,-4.1 29.2,15.7 71.4,18.6 125.5,8.6 50.3,-9.3 89.7,-26.5 113.9,-49.7 24,-23 33.4,-51.6 28.1,-85.1 -0.9,-5.4 2.9,-10.6 8.3,-11.4 5.4,-0.9 10.6,2.9 11.4,8.3 12.6,79.3 -45.1,136.7 -158.2,157.6 -22,4.1 -42.4,6.1 -61,6.1zM792.1,441.1a10,10 0,0 1,-6.7 -2.6c-4.1,-3.7 -4.4,-10 -0.7,-14.1l22.6,-25.1c2.7,-3 3,-7.3 0.9,-10.5 -15.9,-24.1 -39.1,-37.9 -68.9,-41.2 -30.6,-3.4 -67.1,4.3 -108.5,22.7 -5,2.3 -11,-0 -13.2,-5.1 -2.3,-5 0,-11 5.1,-13.2 44.6,-19.9 84.6,-28.1 118.8,-24.3 36,4 64.1,20.8 83.4,50 7.2,10.8 6.1,25.2 -2.7,34.9l-22.6,25.1a10,10 0,0 1,-7.4 3.3zM376.9,831.8c-13.1,0 -26.3,-2.5 -39.6,-7.4 -12.2,-4.5 -19.7,-16.8 -18.4,-29.9l3.5,-33.5c0.6,-5.5 5.5,-9.5 11,-8.9 5.5,0.6 9.5,5.5 8.9,11l-3.5,33.5c-0.4,4 1.8,7.7 5.4,9 26.5,9.8 53,7.7 78.6,-6.5 26.3,-14.5 51,-40.9 73.4,-78.5 2.8,-4.7 9,-6.3 13.7,-3.5s6.3,9 3.5,13.7c-24.3,40.7 -51.5,69.5 -80.9,85.8 -18.2,10.1 -36.8,15.1 -55.7,15.1zM289.1,791.3c-2.5,0 -5.1,-1 -7.1,-2.9 -57,-56.7 -44.1,-137.1 35.4,-220.5 40.9,-43 80.9,-67.3 118.9,-72.4 5.5,-0.7 10.5,3.1 11.3,8.6 0.7,5.5 -3.1,10.5 -8.6,11.3 -33.3,4.5 -69.3,26.8 -107.1,66.4 -35.4,37.1 -57.2,74.2 -63.2,107.2 -5.9,32.7 3.3,61.4 27.4,85.3 3.9,3.9 3.9,10.2 0,14.1a10,10 0,0 1,-7.1 3z"
android:fillColor="#333333"/>
<path
android:pathData="M718,787.5c-4,0 -7.9,-0.8 -11.8,-2.5l-30.8,-13.7c-5.1,-2.3 -7.3,-8.2 -5.1,-13.2s8.2,-7.3 13.2,-5.1l30.8,13.7c3.6,1.6 7.8,0.6 10.2,-2.4 17.5,-22.2 23.6,-48 18.1,-76.7 -5.7,-29.5 -23.1,-61.1 -51.8,-94 -3.6,-4.2 -3.2,-10.5 0.9,-14.1 4.2,-3.6 10.5,-3.2 14.1,0.9 31.1,35.6 50.1,70.4 56.4,103.4 6.7,34.7 -0.8,65.9 -22.1,92.8 -5.5,7 -13.8,10.8 -22.3,10.8zM587.9,820.1c-1.5,0 -3.1,-0.3 -4.6,-1.1 -34.4,-17.6 -65.7,-52.2 -93,-102.7 -27.8,-51.4 -38.7,-96.4 -32.5,-133.7 0.9,-5.4 6.1,-9.1 11.5,-8.2 5.4,0.9 9.1,6.1 8.2,11.5 -5.5,32.8 4.7,73.5 30.3,120.9 25,46.2 54.2,78.8 84.5,94.3a10,10 0,1 1,-4.6 18.9z"
android:fillColor="#333333"/>
<path
android:pathData="M509,524m-70.4,0a70.4,70.4 0,1 0,140.9 0,70.4 70.4,0 1,0 -140.9,0Z"
android:fillColor="#FEDC5A"/>
<path
android:pathData="M509,604.5c-44.3,0 -80.4,-36.1 -80.4,-80.4s36.1,-80.4 80.4,-80.4 80.4,36.1 80.4,80.4 -36.1,80.4 -80.4,80.4zM509,463.6c-33.3,0 -60.4,27.1 -60.4,60.4s27.1,60.4 60.4,60.4 60.4,-27.1 60.4,-60.4 -27.1,-60.4 -60.4,-60.4z"
android:fillColor="#333333"/>
<path
android:pathData="M641.6,802.9c-22,-44.4 -22.4,-126.7 49,-165.5 30.1,-16.3 60.6,-19.5 97.4,-32.2 26.6,-9.3 42.2,-28 48.6,-37.3 0.9,-1.5 2.8,-2 4.3,-1.1 0.7,0.4 1.2,1 1.4,1.8 11.8,32 59,180.4 -39.2,251.6 -43.2,31.3 -96.2,26.9 -125.6,15.4 -22.3,-10.7 -35.9,-32.7 -35.9,-32.7z"
android:fillColor="#54D533"/>
<path
android:pathData="M805.2,609.5S698,639 672,702c0,0 -21,46 -4,123 0,0 -49.8,-19.5 -39.4,-102.8 0,0 23.7,-110.3 176.6,-112.8z"
android:fillColor="#54B721"/>
<path
android:pathData="M726.5,854.2c-9.6,0 -17.9,-0.9 -24.5,-1.9 -5.5,-0.9 -9.2,-6 -8.3,-11.4 0.9,-5.5 6,-9.2 11.4,-8.3 19.6,3.1 57.7,4.5 92.2,-20.5 83.9,-60.8 54,-184 39.7,-228.4 -9,10.2 -24,23.4 -45.6,31 -14.1,4.9 -27,8.3 -39.5,11.6 -20.7,5.5 -38.6,10.3 -56.5,19.9 -35.2,19.2 -49.2,47.7 -54.8,68.3 -7.7,28.7 -4.1,60.5 9.6,83.1 0.4,0.6 6.7,10.4 17.1,19.3a10,10 0,0 1,1.1 14.1,10 10,0 0,1 -14.1,1.1c-13.2,-11.2 -20.8,-23.5 -21.2,-24 -16.5,-27.2 -21,-65 -11.9,-98.8 6.6,-24.4 23.1,-58.1 64.6,-80.7 20,-10.8 39.8,-16.1 60.8,-21.7 12.2,-3.2 24.7,-6.6 38.1,-11.2 24.4,-8.6 38.5,-26 43.5,-33.3 1.8,-2.8 4.6,-4.8 7.9,-5.7 3.4,-0.9 6.9,-0.3 10,1.5 2.7,1.6 4.7,4.1 5.7,7.1 6.4,17.4 21.2,63 22.2,114.2 0.6,29.5 -3.5,56.2 -12.3,79.4 -10.7,28.5 -28.5,51.8 -52.7,69.4 -28.6,20.7 -59.1,25.9 -82.6,25.9zM845.2,573.1z"
android:fillColor="#333333"/>
<path
android:pathData="M614.9,860.2c-4.2,0 -8.1,-2.6 -9.5,-6.8 -1.8,-5.2 1,-10.9 6.3,-12.7 65.5,-22.2 111.2,-69.9 138,-105.9 29.4,-39.5 43.2,-74.1 43.3,-74.4 2,-5.1 7.8,-7.7 13,-5.6 5.1,2 7.7,7.8 5.6,13 -0.6,1.5 -14.7,37 -45.5,78.6 -28.6,38.5 -77.4,89.4 -148,113.4 -1.1,0.4 -2.2,0.5 -3.2,0.5z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,66 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M678.5,502.9m-83.9,0a83.9,83.9 0,1 0,167.9 0,83.9 83.9,0 1,0 -167.9,0Z"
android:fillColor="#FFF6DB"/>
<path
android:pathData="M679.7,427.7s10.1,86.3 -62.8,108.8l-20.2,-92s44.9,-34.8 83,-16.8z"
android:fillColor="#F8E0BB"/>
<path
android:pathData="M531.7,471.5m-115.4,0a115.4,115.4 0,1 0,230.8 0,115.4 115.4,0 1,0 -230.8,0Z"
android:fillColor="#FFF6DB"/>
<path
android:pathData="M647,481.5c-5.5,0 -10,-4.5 -10,-10 0,-58.1 -47.3,-105.4 -105.4,-105.4s-105.4,47.3 -105.4,105.4c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10c0,-69.2 56.3,-125.4 125.4,-125.4s125.4,56.3 125.4,125.4c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M757.4,541.6c-1.1,0 -2.3,-0.2 -3.4,-0.6 -5.2,-1.9 -7.9,-7.6 -6,-12.8 2.9,-8.1 4.4,-16.6 4.4,-25.3 0,-40.8 -33.2,-73.9 -73.9,-73.9 -11.5,0 -22.4,2.5 -32.6,7.6 -4.9,2.4 -10.9,0.4 -13.4,-4.6 -2.4,-4.9 -0.4,-10.9 4.6,-13.4 13,-6.4 26.9,-9.6 41.5,-9.6 51.8,0 93.9,42.1 93.9,93.9 0,11 -1.9,21.8 -5.6,32.1a10,10 0,0 1,-9.4 6.6z"
android:fillColor="#333333"/>
<path
android:pathData="M352.1,355.8l-6.9,-15.6L286.7,356l1.8,16.5c1.5,13 -3.7,25.8 -13.5,34.4 -25.4,22.4 -40.8,54.6 -42,88.9 -0.4,11.9 0.9,24 4.1,36 17.5,65.7 85.4,105.2 151.1,88 61.7,-16.2 100.2,-76.1 91.2,-137.6 -0.7,-4.8 -1.7,-9.7 -3,-14.5 -12.7,-47.1 -51,-80.6 -95.8,-89.3 -12.6,-2.5 -23.4,-10.8 -28.6,-22.6z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M742.3,333.6c-4.6,0 -8.7,-3.2 -9.8,-7.9 -1.2,-5.4 2.2,-10.7 7.6,-11.9 0.5,-0.1 13.4,-3.3 13.7,-13.6 0.2,-8.7 -2.8,-11.8 -7.9,-16.9 -5.8,-5.8 -13.6,-13.6 -13.6,-29.5 0,-22.6 21.9,-32.1 33.4,-34 5.4,-0.9 10.6,2.8 11.5,8.3 0.9,5.4 -2.8,10.6 -8.2,11.5 -0.8,0.1 -16.7,3.1 -16.7,14.3 0,7.6 2.9,10.5 7.8,15.4 6,6 14.3,14.3 13.8,31.6 -0.6,20.8 -19.5,30.4 -29.4,32.6 -0.7,0.2 -1.4,0.2 -2.2,0.2zM666.5,333.6c-4.6,0 -8.7,-3.2 -9.8,-7.9 -1.2,-5.4 2.2,-10.7 7.6,-11.9 0.5,-0.1 13.4,-3.3 13.7,-13.6 0.2,-8.2 -2.9,-11.5 -8.1,-17 -5.7,-6 -13.4,-14.2 -13.4,-29.4 0,-22.6 21.9,-32.1 33.4,-34 5.4,-0.9 10.6,2.8 11.5,8.3 0.9,5.4 -2.8,10.6 -8.2,11.5 -0.8,0.1 -16.7,3.1 -16.7,14.3 0,7.2 3,10.4 8,15.7 5.9,6.3 14.1,14.9 13.6,31.3 -0.6,20.8 -19.5,30.4 -29.4,32.6 -0.7,0.2 -1.4,0.2 -2.2,0.2zM590.8,333.6c-4.6,0 -8.7,-3.2 -9.8,-7.9 -1.2,-5.4 2.2,-10.7 7.6,-11.9 0.5,-0.1 13.4,-3.3 13.7,-13.6 0.2,-8.2 -2.9,-11.5 -8.1,-17 -5.7,-6 -13.4,-14.2 -13.4,-29.4 0,-22.6 21.9,-32.1 33.4,-34 5.4,-0.9 10.6,2.8 11.5,8.3 0.9,5.4 -2.8,10.6 -8.2,11.5 -0.8,0.1 -16.7,3.1 -16.7,14.3 0,7.2 3,10.4 8,15.7 5.9,6.3 14.1,14.9 13.6,31.3 -0.6,20.8 -19.5,30.4 -29.4,32.6 -0.7,0.2 -1.4,0.2 -2.2,0.2z"
android:fillColor="#333333"/>
<path
android:pathData="M290,401.9s-31.1,52.8 -9.1,124.2h-42.7s-21,-81.5 51.8,-124.2z"
android:fillColor="#F29816"/>
<path
android:pathData="M342.5,341L326,283.3c-1.7,-6.1 0.8,-12.4 6,-15.9 11.3,-7.6 16.9,-21.9 12.6,-35.7 -4.8,-15.6 -21.1,-25 -37,-21.4 -7.6,1.7 -14,6 -18.3,11.7 -3.2,4.2 -8.9,5.7 -13.8,3.7a31.5,31.5 0,0 0,-21.7 -0.9c-15.5,4.9 -24.8,21.2 -21.2,37.1 3.2,14.1 15.4,23.7 29,24.5 6.2,0.4 11.6,4.6 13.2,10.6l15.4,58.1"
android:fillColor="#FFF6DB"/>
<path
android:pathData="M358,633.9c-59.2,0 -113.6,-39.7 -129.5,-99.4 -3.4,-12.7 -4.9,-25.8 -4.5,-38.9 1.2,-36.7 17.7,-71.7 45.4,-96.1 7.4,-6.6 11.2,-16.2 10.2,-25.8l-1.8,-16.5a10,10 0,0 1,7.3 -10.8l58.5,-15.8c4.8,-1.3 9.8,1.1 11.8,5.6l6.9,15.6c3.8,8.6 11.8,14.9 21.3,16.8 24.2,4.8 46.6,16.1 64.8,32.7 18.7,17.1 32.1,39.2 38.8,63.8 1.4,5.2 2.5,10.4 3.3,15.7 9.9,67.5 -32.5,131.4 -98.6,148.7 -11.3,3 -22.6,4.4 -33.8,4.4zM298.6,363.4l0.9,8c1.8,16.1 -4.5,32.2 -16.8,43 -23.5,20.7 -37.6,50.5 -38.6,81.7 -0.4,11.1 0.9,22.2 3.8,33.1 13.5,50.8 59.8,84.6 110.1,84.6 9.5,0 19.2,-1.2 28.8,-3.7 56.2,-14.7 92.3,-69.1 83.9,-126.5 -0.6,-4.5 -1.6,-9 -2.8,-13.4 -5.7,-20.9 -17,-39.7 -33,-54.3a114.2,114.2 0,0 0,-55.2 -27.9c-15.9,-3.1 -29.3,-13.7 -35.8,-28.3l-3.4,-7.7 -42,11.3z"
android:fillColor="#333333"/>
<path
android:pathData="M291.1,365.1c-4.4,0 -8.5,-3 -9.7,-7.4l-15.4,-58.1c-0.5,-1.8 -2.1,-3.1 -4.1,-3.2 -18.3,-1.1 -34,-14.4 -38.1,-32.3 -4.8,-20.9 7.5,-42.4 27.9,-48.9a41.7,41.7 0,0 1,28.6 1.2c0.7,0.3 1.5,0.1 2,-0.5 5.9,-7.8 14.5,-13.3 24.1,-15.4 20.9,-4.7 42.3,7.8 48.7,28.2 5.4,17.5 -1.4,36.8 -16.6,47 -1.7,1.1 -2.5,3.1 -2,4.9l16.5,57.7c1.5,5.3 -1.5,10.9 -6.9,12.4 -5.3,1.5 -10.9,-1.5 -12.4,-6.9l-16.5,-57.7c-2.9,-10.2 1.1,-21 10.1,-27 8,-5.4 11.5,-15.2 8.6,-24.4 -3.3,-10.6 -14.4,-17.1 -25.3,-14.6 -5.1,1.1 -9.4,3.9 -12.5,8 -6,7.8 -16.5,10.7 -25.6,6.9 -4.8,-2 -9.9,-2.2 -14.9,-0.6 -10.6,3.4 -17,14.5 -14.5,25.4 2.1,9.3 10.3,16.2 19.8,16.8 10.6,0.6 19.6,7.9 22.3,18l15.4,58.1c1.4,5.3 -1.8,10.8 -7.1,12.2 -0.9,0.2 -1.7,0.3 -2.6,0.3z"
android:fillColor="#333333"/>
<path
android:pathData="M155,534.4m38,0l607,0q38,0 38,38l0,3.7q0,38 -38,38l-607,0q-38,0 -38,-38l0,-3.7q0,-38 38,-38Z"
android:fillColor="#FEC773"/>
<path
android:pathData="M195.9,574.3c0,-22 17.9,-39.9 39.9,-39.9h-33.6c-22,0 -39.9,17.9 -39.9,39.9 0,22 17.9,39.9 39.9,39.9h33.6c-22,0 -39.9,-17.9 -39.9,-39.9z"
android:fillColor="#F29816"/>
<path
android:pathData="M194.9,614.2h603.3v25.7c0,87.8 -71.2,159 -159,159H353.9c-87.8,0 -159,-71.2 -159,-159v-25.7z"
android:fillColor="#FEC773"/>
<path
android:pathData="M239.6,623.8s-3.9,167.6 140.9,167.6c0,0 -179.4,23.6 -185.7,-167.6h44.8z"
android:fillColor="#F29816"/>
<path
android:pathData="M631.3,808.8H361.7c-97.5,0 -176.8,-79.3 -176.8,-176.8v-15.8c0,-5.5 4.5,-10 10,-10s10,4.5 10,10V632c0,86.5 70.3,156.8 156.8,156.8h269.6c86.5,0 156.8,-70.3 156.8,-156.8v-15.8c0,-5.5 4.5,-10 10,-10s10,4.5 10,10V632c0,97.5 -79.3,176.8 -176.8,176.8z"
android:fillColor="#333333"/>
<path
android:pathData="M798.1,624.2H399.5c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h398.7c16.5,0 29.9,-13.4 29.9,-29.9s-13.4,-29.9 -29.9,-29.9H194.9c-16.5,0 -29.9,13.4 -29.9,29.9s13.4,29.9 29.9,29.9h84.6c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-84.6c-27.5,0 -49.9,-22.4 -49.9,-49.9s22.4,-49.9 49.9,-49.9h603.3c27.5,0 49.9,22.4 49.9,49.9s-22.4,49.9 -49.9,49.9z"
android:fillColor="#333333"/>
<path
android:pathData="M875.6,686H626.8c-8.8,0 -15.6,7.7 -14.6,16.5 5.8,49.2 37,90.5 80.2,110.6 5.1,2.4 8.4,7.6 8.4,13.3 0,8.1 6.6,14.7 14.7,14.7h71.6c8.1,0 14.7,-6.6 14.7,-14.7 0,-5.7 3.2,-10.9 8.4,-13.3 43.2,-20 74.4,-61.4 80.2,-110.6 1,-8.8 -5.8,-16.5 -14.6,-16.5z"
android:fillColor="#FFF6DB"/>
<path
android:pathData="M653.2,692.5s0.3,72.3 49.1,117.9c0,0 -80.1,-17.1 -86.2,-119.7l37.1,1.9z"
android:fillColor="#F8E0BB"/>
<path
android:pathData="M787,851H715.4c-13.6,0 -24.7,-11.1 -24.7,-24.7 0,-1.8 -1,-3.5 -2.6,-4.2 -22.9,-10.6 -43,-27.1 -58,-47.5 -15.3,-20.8 -24.9,-45.3 -27.9,-70.9 -0.8,-7 1.4,-14.1 6.1,-19.4a24.7,24.7 0,0 1,18.4 -8.3h248.9c7,0 13.8,3 18.4,8.3 4.7,5.3 6.9,12.3 6.1,19.4 -3,25.6 -12.7,50.1 -27.9,70.9 -15,20.4 -35,36.9 -58,47.5 -1.6,0.7 -2.6,2.4 -2.6,4.2 0,13.6 -11.1,24.7 -24.7,24.7zM626.8,696c-1.8,0 -3,1 -3.5,1.6 -0.5,0.6 -1.4,1.9 -1.2,3.8 5.2,44.4 33.7,83.8 74.4,102.6 8.6,4 14.2,12.8 14.2,22.3 0,2.6 2.1,4.7 4.7,4.7h71.6c2.6,0 4.7,-2.1 4.7,-4.7 0,-9.6 5.6,-18.3 14.2,-22.3 40.7,-18.9 69.2,-58.2 74.4,-102.6 0.2,-1.9 -0.6,-3.2 -1.2,-3.8 -0.5,-0.6 -1.7,-1.6 -3.5,-1.6H626.8z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M190.9,606.9c84.3,64.9 189.9,103.6 304.6,103.6s221.4,-39.1 306,-104.6L506.3,228.8c-7.1,-9.1 -20.9,-9 -27.9,0.2L190.9,606.9z"
android:fillColor="#F9675A"/>
<path
android:pathData="M496.2,710.5c-114.7,0 -220.3,-38.7 -304.6,-103.6l-46.7,61.3c-10.3,13.5 -7.1,32.8 6.9,42.3 203.6,139.1 479,143.1 689,-4.8 13.9,-9.8 16.8,-29.1 6.3,-42.4l-45,-57.5C717.6,671.4 611.4,710.5 496.2,710.5z"
android:fillColor="#54B721"/>
<path
android:pathData="M497.4,771.1c129.1,0 248,-47.6 342.8,-113.3l-34.6,-39.5c-85.2,59.2 -192.1,94.4 -308.2,94.4S280.9,667.6 196,609.1l-39.4,50.1c94.5,64.8 212.6,111.9 340.8,111.9z"
android:fillColor="#D8E032"/>
<path
android:pathData="M477.3,363.6c-0.2,-9.1 5.9,-18.1 14.9,-24.1a6.3,6.3 0,0 1,7 -0c8.9,5.9 14.9,14.7 14.9,23.8 0,10.1 -8.1,18.3 -18.2,18.4s-18.4,-8 -18.5,-18zM477.3,613.4c-0.2,-9.1 5.9,-18.1 14.9,-24.1a6.3,6.3 0,0 1,7 -0c8.9,5.9 14.9,14.7 14.9,23.8 0,10.1 -8.1,18.3 -18.2,18.4 -10.1,0.1 -18.4,-8 -18.5,-18zM400.5,488c-0.2,-9.1 5.9,-18.1 14.9,-24.1a6.3,6.3 0,0 1,7 -0c8.9,5.9 14.9,14.7 14.9,23.8 0,10.1 -8.1,18.3 -18.2,18.4 -10.1,0.1 -18.4,-8 -18.5,-18zM556.5,488c-0.2,-9.1 5.9,-18.1 14.9,-24.1a6.3,6.3 0,0 1,7 -0c8.9,5.9 14.9,14.7 14.9,23.8 0,10.1 -8.1,18.3 -18.2,18.4 -10.1,0.1 -18.4,-8 -18.5,-18zM630.2,590.8c-0.2,-9.1 5.9,-18.1 14.9,-24.1a6.3,6.3 0,0 1,7 -0c8.9,5.9 14.9,14.7 14.9,23.8 0,10.1 -8.1,18.3 -18.2,18.4 -10.1,0.1 -18.4,-8 -18.5,-18zM325.6,590.8c-0.2,-9.1 5.9,-18.1 14.9,-24.1a6.3,6.3 0,0 1,7 -0c8.9,5.9 14.9,14.7 14.9,23.8 0,10.1 -8.1,18.3 -18.2,18.4 -10.1,0.1 -18.4,-8 -18.5,-18z"
android:fillColor="#000333"/>
<path
android:pathData="M487,236L261,577s-14,18 5,41c0,0 37.9,46.8 68,66 0,0 -95.1,-39.9 -138,-74.9L487,236z"
android:fillColor="#E2433B"/>
<path
android:pathData="M190.9,616.9c-2.1,0 -4.2,-0.7 -6.1,-2 -4.4,-3.3 -5.3,-9.6 -1.9,-14L469.2,224.7c5.5,-7.3 14,-11.5 23.1,-11.6 9.1,-0.1 17.6,4 23.3,11.2l293.8,375.4c3.4,4.3 2.6,10.6 -1.7,14 -4.3,3.4 -10.6,2.6 -14,-1.7L499.8,236.7c-1.8,-2.3 -4.5,-3.6 -7.4,-3.6 -2.9,0 -5.6,1.4 -7.3,3.7L198.8,613c-2,2.6 -4.9,3.9 -8,3.9z"
android:fillColor="#333333"/>
<path
android:pathData="M496.2,720.5c-66.4,0 -131.1,-12.6 -192.1,-37.5 -5.1,-2.1 -7.6,-7.9 -5.5,-13 2.1,-5.1 7.9,-7.6 13,-5.5 58.6,23.9 120.7,36 184.6,36 55.3,0 109.5,-9.1 161.2,-27.2 50,-17.4 96.6,-42.8 138.6,-75.4 4.3,-3.4 10.6,-2.6 14,1.7l45,57.5c3.4,4.3 2.6,10.6 -1.7,14 -4.3,3.4 -10.6,2.6 -14,-1.7l-38.9,-49.7c-41.6,31 -87.5,55.4 -136.4,72.4 -53.8,18.8 -110.3,28.3 -167.8,28.3z"
android:fillColor="#333333"/>
<path
android:pathData="M493.3,825.8c-57.7,0 -115,-8.1 -170.5,-24 -63.1,-18.1 -122.6,-46 -176.6,-83 -9.1,-6.2 -15,-15.6 -16.8,-26.4 -1.8,-10.8 0.9,-21.5 7.6,-30.3l46.7,-61.3c3.3,-4.4 9.6,-5.3 14,-1.9 4.4,3.3 5.3,9.6 1.9,14l-46.7,61.3c-3.3,4.3 -4.6,9.6 -3.7,14.9 0.9,5.4 3.8,10 8.3,13.1 52.3,35.7 109.7,62.7 170.8,80.3a597,597 0,0 0,185.5 22.9c5.5,-0.2 10.1,4.1 10.3,9.6 0.2,5.5 -4.1,10.1 -9.6,10.3 -7,0.2 -14.1,0.4 -21.1,0.4z"
android:fillColor="#333333"/>
<path
android:pathData="M549.6,771.4c77.6,77.7 203.5,77.7 281.2,0.1 70.5,-70.5 77,-180.8 19.5,-258.6 -9.4,-12.7 -27.9,-14.1 -39.1,-3l-261.6,261.5z"
android:fillColor="#FFB000"/>
<path
android:pathData="M672.3,681.1l-66.1,66.1c-1.9,1.9 -1.9,5.7 0,7.6 20.1,16.4 44.7,25.8 69.3,29 3.2,0.6 5.7,-1.9 5,-5v-94.5c0.6,-4.4 -5,-6.3 -8.2,-3.2zM742.6,623.4h94.5c2.5,0 5,-2.5 5,-5 -2.5,-25.2 -12,-48.5 -29,-69.3 -1.9,-1.9 -5,-2.5 -7.6,0l-66.1,66.1c-3.8,2.5 -1.9,8.2 3.2,8.2zM703.4,676v103c0,2.8 2.8,5.5 5.5,5.5 27.5,-2.8 52.9,-13 75.5,-31.6 2.1,-2.1 2.8,-5.5 0,-8.2l-72.1,-72.1c-2.8,-4.1 -8.9,-2.1 -8.9,3.4zM729.6,655.3l72.8,72.8c2.1,2.1 6.2,2.1 8.2,0 17.9,-22 28.1,-48.7 31.6,-75.5 0.7,-3.4 -2.1,-6.2 -5.5,-5.5l-103,-1.4c-5.5,0 -7.6,6.2 -4.1,9.6z"
android:fillColor="#ED7A1F"/>
<path
android:pathData="M690,839.6c-44.8,0 -89.8,-14.3 -127.5,-43.5a32.5,32.5 0,0 1,-12.5 -23.6,32.6 32.6,0 0,1 9.5,-25.1l222,-222c3.9,-3.9 10.2,-3.9 14.1,0s3.9,10.2 0,14.1l-222,222c-2.6,2.6 -3.9,6.1 -3.7,9.7 0.2,3.6 1.9,6.9 4.8,9.1 74.8,58 181.9,51.1 248.9,-15.9 33.5,-33.5 53.1,-78 55.2,-125.3 2,-47 -13.4,-92.8 -43.3,-128.8 -3.5,-4.3 -3,-10.6 1.3,-14.1 4.3,-3.5 10.6,-3 14.1,1.3 33.2,39.9 50.2,90.5 48,142.5 -2.3,52.3 -23.9,101.6 -61,138.6 -40.5,40.4 -94,61.1 -147.8,61.1z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,63 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M442.9,330.6L305.5,330.6c-9.5,0 -16.8,-2.2 -21.9,-6.6s-8.6,-10 -10.7,-16.8c-2,-6.8 -3,-14.4 -3,-22.9 0,-8.5 0.7,-16.5 2,-23.9 0.7,-7.5 2,-15.6 4.1,-24.4 2,-8.8 4.9,-16.3 8.6,-22.4 3.7,-6.1 8.6,-10.2 14.8,-12.2 6.1,-2 13.6,-0.3 22.4,5.1 10.2,6.1 21.7,12.7 34.6,19.8a1861.1,1861.1 0,0 1,37.7 21.4c12.2,7.1 23.6,13.6 34.1,19.3s18.5,10.4 23.9,13.7c6.8,4.8 11.9,10 15.3,15.8 3.4,5.8 4.8,11.2 4.1,16.3 -0.7,5.1 -3.4,9.3 -8.1,12.7 -4.8,3.4 -11.5,5.1 -20.4,5.1zM522.3,329.6h136.4c9.5,0 16.8,-2.2 21.9,-6.6s8.6,-10 10.7,-16.8c2,-6.8 3,-14.4 3,-22.9 0,-8.5 -0.3,-16.5 -1,-23.9 -1.4,-7.5 -2.9,-15.4 -4.6,-23.9 -1.7,-8.5 -4.4,-15.8 -8.1,-21.9 -3.7,-6.1 -8.6,-10.2 -14.8,-12.2 -6.1,-2 -13.6,-0.7 -22.4,4.1 -10.2,6.1 -21.7,12.7 -34.6,19.8 -12.9,7.1 -25.6,14.3 -38.2,21.4 -12.6,7.1 -24.1,13.6 -34.6,19.3 -10.5,5.8 -18.1,10.4 -22.9,13.7 -7.5,4.8 -12.9,10 -16.3,15.8 -3.4,5.8 -4.8,11.2 -4.1,16.3 0.7,5.1 3.4,9.3 8.1,12.7s11.9,5.1 21.4,5.1z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M442.9,340.6L305.5,340.6c-11.9,0 -21.5,-3 -28.4,-9.1 -6.5,-5.7 -11.1,-12.9 -13.7,-21.5 -2.3,-7.7 -3.5,-16.4 -3.5,-25.8 0,-8.9 0.7,-17.4 2.1,-25.3 0.7,-7.8 2.2,-16.3 4.2,-25.3 2.3,-9.8 5.6,-18.4 9.9,-25.4 5,-8.1 11.8,-13.7 20.1,-16.5 9,-3 19.4,-1 30.8,6 10,6 21.5,12.6 34.2,19.6 12.9,7.1 25.6,14.4 37.9,21.5 4.8,2.8 6.4,8.9 3.6,13.7s-8.9,6.4 -13.7,3.6c-12.1,-7.1 -24.7,-14.2 -37.5,-21.3 -12.9,-7.1 -24.7,-13.9 -34.9,-20 -0,-0 -0.1,-0 -0.1,-0.1 -6,-3.7 -10.9,-5.1 -14,-4.1 -3.8,1.3 -6.9,3.9 -9.4,7.9 -3.2,5.2 -5.7,11.7 -7.4,19.4 -1.9,8.3 -3.2,16.1 -3.9,23.1 -0,0.3 -0.1,0.6 -0.1,0.9 -1.2,6.8 -1.9,14.3 -1.9,22.1s0.9,14.2 2.6,20c1.5,5 4,8.9 7.7,12.1 3.2,2.8 8.4,4.2 15.3,4.2h137.4c6.6,0 11.6,-1.1 14.5,-3.2 3.2,-2.3 3.8,-4.3 4,-5.9 0.4,-2.8 -0.6,-6.1 -2.8,-9.9 -2.8,-4.8 -1.2,-10.9 3.5,-13.7 4.8,-2.8 10.9,-1.2 13.7,3.5 4.5,7.7 6.3,15.3 5.4,22.7 -1,7.8 -5.3,14.6 -12.2,19.5 -6.5,4.6 -15.3,6.9 -26.2,6.9zM658.7,339.6L522.3,339.6c-11.7,0 -20.6,-2.3 -27.2,-6.9 -7,-5 -11.2,-11.7 -12.2,-19.5 -1,-7.3 0.8,-15 5.4,-22.7 4.2,-7.1 10.6,-13.4 19.3,-19 5.1,-3.6 12.9,-8.3 23.7,-14.2 10.4,-5.7 22,-12.2 34.5,-19.3 12.5,-7.1 25.4,-14.3 38.3,-21.4 12.7,-7 24.3,-13.6 34.3,-19.7 0.1,-0.1 0.3,-0.2 0.4,-0.2 11.3,-6.1 21.5,-7.7 30.3,-4.8 8.4,2.8 15.1,8.3 20.1,16.5 4.3,7.1 7.5,15.5 9.4,25.1a10,10 0,0 1,-7.8 11.8c-5.4,1.1 -10.7,-2.4 -11.8,-7.8 -1.5,-7.3 -3.8,-13.6 -6.9,-18.6 -2.5,-4.1 -5.6,-6.7 -9.4,-7.9 -3.3,-1.1 -8.2,0 -14.3,3.3 -10.2,6.1 -21.9,12.8 -34.7,19.9a3686,3686 0,0 0,-38.1 21.3c-12.6,7.1 -24.2,13.6 -34.7,19.4 -10.1,5.6 -17.5,10 -21.9,13.1 -0.2,0.1 -0.3,0.2 -0.4,0.3 -6.1,3.9 -10.5,8 -13,12.4 -2.2,3.8 -3.2,7.1 -2.8,9.9 0.2,1.5 0.9,3.6 4,5.9 2.1,1.5 6.4,3.2 15.6,3.2h136.4c7,0 12.1,-1.4 15.3,-4.2 3.7,-3.2 6.2,-7.1 7.7,-12.1 1.6,-5.3 7.2,-8.3 12.4,-6.7 5.3,1.6 8.3,7.2 6.7,12.4 -2.6,8.6 -7.2,15.8 -13.7,21.5 -6.9,6 -16.5,9.1 -28.4,9.1z"
android:fillColor="#333333"/>
<path
android:pathData="M149,291.4m29.8,0l606.6,0q29.8,0 29.8,29.8l0,95.2q0,29.8 -29.8,29.8l-606.6,0q-29.8,0 -29.8,-29.8l0,-95.2q0,-29.8 29.8,-29.8Z"
android:fillColor="#EA5959"/>
<path
android:pathData="M180.6,435.7h47.1c-15.5,0 -28,-12.5 -28,-28v-83.1c0,-15.5 12.5,-28 28,-28h-47.1c-15.5,0 -28,12.5 -28,28v83.1c0,15.5 12.5,28 28,28z"
android:fillColor="#CE4141"/>
<path
android:pathData="M195.7,494.4h572.8v275.5c0,17 -13.8,30.9 -30.9,30.9h-511.1c-17,0 -30.9,-13.8 -30.9,-30.9v-275.5z"
android:fillColor="#EA5959"/>
<path
android:pathData="M195.7,445.5h572.8v48.7H195.7z"
android:fillColor="#CE4141"/>
<path
android:pathData="M426.2,291.4h111.9v154.8H426.2z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M426.2,494.3h111.9v267.8H426.2z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M426.2,444.1h111.9v50.2H426.2z"
android:fillColor="#F29816"/>
<path
android:pathData="M785.4,454.1H178.8c-22,0 -39.8,-17.9 -39.8,-39.8v-95.2c0,-22 17.9,-39.8 39.8,-39.8h606.6c22,0 39.8,17.9 39.8,39.8v95.2c0,22 -17.9,39.8 -39.8,39.8zM178.8,299.2c-10.9,0 -19.8,8.9 -19.8,19.8v95.2c0,10.9 8.9,19.8 19.8,19.8h606.6c10.9,0 19.8,-8.9 19.8,-19.8v-95.2c0,-10.9 -8.9,-19.8 -19.8,-19.8H178.8z"
android:fillColor="#333333"/>
<path
android:pathData="M207.8,723.3s-3.1,38.7 42.9,38.7h473.8s44.5,-4.2 44.5,-38.7v61.4S763.1,807 727.6,807H230.5s-31.8,-3.9 -31.8,-23.9l9,-59.8z"
android:fillColor="#CE4141"/>
<path
android:pathData="M425.9,762h111.9v38.7H425.9z"
android:fillColor="#F29816"/>
<path
android:pathData="M578,811.1H230.1c-23.3,0 -42.3,-19 -42.3,-42.3V530.9c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v238c0,12.3 10,22.3 22.3,22.3H578c5.5,0 10,4.5 10,10s-4.5,10 -10,10zM770.7,544c-5.5,0 -10,-4.5 -10,-10v-88.9c0,-5.5 4.5,-10 10,-10s10,4.5 10,10V534c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M425.9,740.7c-5.5,0 -10,-4.5 -10,-10v-280.3c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v280.3c0,5.5 -4.5,10 -10,10zM537.8,805.4c-5.5,0 -10,-4.5 -10,-10V534c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v261.4c0,5.5 -4.5,10 -10,10zM537.8,445.7c-5.5,0 -10,-4.5 -10,-10v-99.4c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v99.4c0,5.5 -4.5,10 -10,10zM425.9,408c-5.5,0 -10,-4.5 -10,-10v-99.4c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v99.4c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M755,720m-140.7,0a140.7,140.7 0,1 0,281.4 0,140.7 140.7,0 1,0 -281.4,0Z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M728,587s-71,34 -71,143c0,0 1.9,118.5 123.9,118.5 0,0 -140.4,52.5 -166.6,-128.5 0,0 -0.3,-123 113.7,-133z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M755,870.6c-38.6,0 -77.2,-14.7 -106.6,-44.1 -28.5,-28.5 -44.1,-66.3 -44.1,-106.6s15.7,-78.1 44.1,-106.6c58.8,-58.8 154.4,-58.8 213.1,0 20.3,20.3 34.3,45.7 40.5,73.5 6.1,27.1 4.6,55.2 -4.3,81.5a10,10 0,0 1,-12.7 6.3,10 10,0 0,1 -6.3,-12.7c7.7,-22.8 9,-47.2 3.7,-70.7 -5.4,-24.1 -17.5,-46.2 -35.1,-63.7 -51,-51 -133.9,-51 -184.9,0 -24.7,24.7 -38.3,57.5 -38.3,92.4s13.6,67.7 38.3,92.4c51,51 133.9,51 184.9,0 3.9,-3.9 10.2,-3.9 14.1,0s3.9,10.2 0,14.1c-29.4,29.4 -68,44.1 -106.6,44.1z"
android:fillColor="#333333"/>
<path
android:pathData="M756,644l23.8,48.2 53.2,7.7 -38.5,37.5 9.1,53L756,765.4l-47.6,25 9.1,-53 -38.5,-37.5 53.2,-7.7L756,644z"
android:fillColor="#FFEBA4"/>
<path
android:pathData="M803.6,800.4c-1.6,0 -3.2,-0.4 -4.7,-1.1L756,776.7l-42.9,22.6a10,10 0,0 1,-10.5 -0.8,10 10,0 0,1 -4,-9.8l8.2,-47.8 -34.7,-33.8c-2.7,-2.7 -3.7,-6.6 -2.5,-10.3s4.3,-6.3 8.1,-6.8l48,-7 21.5,-43.5c1.7,-3.4 5.2,-5.6 9,-5.6s7.3,2.2 9,5.6l23.8,48.2c2.4,4.9 0.4,10.9 -4.5,13.4 -4.9,2.4 -10.9,0.4 -13.4,-4.5L756,666.6l-14.8,30c-1.5,3 -4.3,5 -7.5,5.5l-33.1,4.8 24,23.4c2.4,2.3 3.4,5.6 2.9,8.9l-5.7,33 29.6,-15.6c2.9,-1.5 6.4,-1.5 9.3,0l29.6,15.6 -5.7,-33c-0.6,-3.2 0.5,-6.6 2.9,-8.9l38.5,-37.5c4,-3.8 10.3,-3.8 14.1,0.2 3.8,4 3.8,10.3 -0.2,14.1l-34.7,33.8 8.2,47.8c0.6,3.8 -0.9,7.5 -4,9.8a10,10 0,0 1,-5.9 1.9z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,54 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M455.8,189.3h243.1c38.3,0 69.5,31.1 69.5,69.5v485.5H386.4V258.8c0,-38.3 31.1,-69.5 69.5,-69.5z"
android:fillColor="#54D533"/>
<path
android:pathData="M768.4,548c-5.5,0 -10,-4.5 -10,-10V257.6c0,-31.2 -25.4,-56.5 -56.5,-56.5H452.9c-31.2,0 -56.5,25.4 -56.5,56.5v105.6c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V257.6c0,-42.2 34.3,-76.5 76.5,-76.5H701.9c42.2,0 76.5,34.3 76.5,76.5V538c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M489.4,712.7H210.2V523.1c0,-19.4 12,-36.8 30.1,-43.7l185.6,-71c30.6,-11.7 63.5,10.9 63.5,43.7v260.5z"
android:fillColor="#44A00E"/>
<path
android:pathData="M146.8,714.6m58.9,0l564.9,0q58.9,0 58.9,58.9l0,-0q0,58.9 -58.9,58.9l-564.9,0q-58.9,0 -58.9,-58.9l0,0q0,-58.9 58.9,-58.9Z"
android:fillColor="#54D533"/>
<path
android:pathData="M771.8,832.3H206.8c-32.5,0 -58.9,-26.4 -58.9,-58.9v0.5h682.7v-0.5c0,32.5 -26.4,58.9 -58.9,58.9z"
android:fillColor="#44A00E"/>
<path
android:pathData="M450.5,256.9m35.4,0l185.8,0q35.4,0 35.4,35.4l0,0q0,35.4 -35.4,35.4l-185.8,0q-35.4,0 -35.4,-35.4l0,0q0,-35.4 35.4,-35.4Z"
android:fillColor="#D8F9CC"/>
<path
android:pathData="M547.2,373.2m35.4,0l89,0q35.4,0 35.4,35.4l0,0q0,35.4 -35.4,35.4l-89,0q-35.4,0 -35.4,-35.4l0,0q0,-35.4 35.4,-35.4Z"
android:fillColor="#D8F9CC"/>
<path
android:pathData="M547.2,489.6m35.4,0l89,0q35.4,0 35.4,35.4l0,0q0,35.4 -35.4,35.4l-89,0q-35.4,0 -35.4,-35.4l0,0q0,-35.4 35.4,-35.4Z"
android:fillColor="#D8F9CC"/>
<path
android:pathData="M317.8,583.4h64.4c15.5,0 28.1,12.6 28.1,28.1v92.5H289.6v-92.5c0,-15.5 12.6,-28.1 28.1,-28.1zM249.4,482.9v225.4l-33.5,-0.4V519.1s-1.9,-31.5 33.5,-36.3z"
android:fillColor="#377F08"/>
<path
android:pathData="M210.2,722.7c-5.5,0 -10,-4.5 -10,-10V523.1c0,-23.4 14.7,-44.7 36.5,-53l185.6,-71a56.8,56.8 0,0 1,52.5 6.3,56.8 56.8,0 0,1 24.6,46.8v206c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V452.1c0,-12.3 -5.8,-23.3 -15.9,-30.3 -10.1,-7 -22.5,-8.4 -34,-4.1l-185.6,71c-14.1,5.4 -23.6,19.2 -23.6,34.3v189.6c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M592,842.3H205.6c-38,0 -68.9,-30.9 -68.9,-68.9s30.9,-68.9 68.9,-68.9h564.9c5.5,0 10,4.5 10,10s-4.5,10 -10,10H205.6c-27,0 -48.9,21.9 -48.9,48.9s21.9,48.9 48.9,48.9H592c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M749.3,728m-134.7,0a134.7,134.7 0,1 0,269.5 0,134.7 134.7,0 1,0 -269.5,0Z"
android:fillColor="#F76C69"/>
<path
android:pathData="M723.4,600.6s-68,32.6 -68,136.9c0,0 1.8,113.4 118.7,113.4 0,0 -134.4,50.3 -159.6,-123 0,0 -0.3,-117.8 108.9,-127.3z"
android:fillColor="#E54E4E"/>
<path
android:pathData="M749.3,872.7c-38.7,0 -75,-15.1 -102.3,-42.4 -27.3,-27.3 -42.4,-63.7 -42.4,-102.3s15.1,-75 42.4,-102.3c56.4,-56.4 148.3,-56.4 204.7,0C879,653 894,689.3 894,728s-15.1,75 -42.4,102.3c-27.3,27.3 -63.7,42.4 -102.3,42.4zM749.3,603.3c-31.9,0 -63.9,12.2 -88.2,36.5 -23.6,23.6 -36.5,54.9 -36.5,88.2s13,64.6 36.5,88.2c23.6,23.6 54.9,36.5 88.2,36.5s64.6,-13 88.2,-36.5c23.6,-23.6 36.5,-54.9 36.5,-88.2s-13,-64.6 -36.5,-88.2c-24.3,-24.3 -56.3,-36.5 -88.2,-36.5z"
android:fillColor="#333333"/>
<path
android:pathData="M771.1,736.6c0.1,-0.7 0.1,-1.4 0.1,-2v-51.8c0,-12.1 -9.8,-22 -22,-22s-22,9.8 -22,22v51.8c0,0.9 0.1,1.8 0.2,2.7 -8.3,6.6 -13.7,16.8 -13.7,28.2 0,19.8 16.1,35.9 35.9,35.9s35.9,-16.1 35.9,-35.9c0,-11.8 -5.7,-22.3 -14.5,-28.8z"
android:fillColor="#FFEBA4"/>
<path
android:pathData="M749.7,811c-25.3,0 -45.9,-20.6 -45.9,-45.9 0,-12.4 4.9,-23.9 13.5,-32.5v-50.1c0,-17.6 14.3,-32 32,-32s32,14.3 32,32v49.3c9.1,8.6 14.4,20.7 14.4,33.3 0,25.3 -20.6,45.9 -45.9,45.9zM749.3,670.4c-6.6,0 -12,5.4 -12,12v51.8c0,0.5 0,0.9 0.1,1.5 0.4,3.5 -1,6.9 -3.7,9 -6.3,5 -9.9,12.4 -9.9,20.3 0,14.3 11.6,25.9 25.9,25.9s25.9,-11.6 25.9,-25.9c0,-8.3 -3.8,-15.8 -10.4,-20.8a10,10 0,0 1,-4 -8.9c0,-0.4 0.1,-0.8 0.1,-1.1v-51.8c0,-6.6 -5.4,-12 -12,-12z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,57 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M718.7,394.5h-68.5V290.2c0,-10.6 -8.6,-19.2 -19.2,-19.2H368.9c-10.6,0 -19.2,8.6 -19.2,19.2v104.3H281.2V290.2c0,-48.3 39.3,-87.7 87.7,-87.7h262.2c48.3,0 87.7,39.3 87.7,87.7v104.3z"
android:fillColor="#CE4141"/>
<path
android:pathData="M219.6,421.9m49.2,0l462.2,0q49.2,0 49.2,49.2l0,301.3q0,49.2 -49.2,49.2l-462.2,0q-49.2,0 -49.2,-49.2l0,-301.3q0,-49.2 49.2,-49.2Z"
android:fillColor="#EA5959"/>
<path
android:pathData="M175.3,334.1m49.2,0l549.9,0q49.2,0 49.2,49.2l0,42.9q0,49.2 -49.2,49.2l-549.9,0q-49.2,0 -49.2,-49.2l0,-42.9q0,-49.2 49.2,-49.2Z"
android:fillColor="#FEDC5A"/>
<path
android:pathData="M175.3,430.4h648.4c0,24.8 -20.2,45 -45,45H220.3c-24.8,0 -45,-20.2 -45,-45z"
android:fillColor="#F29816"/>
<path
android:pathData="M254,469.8v284.8s-1.6,36.9 27.2,36.9h368.6v30.2H267.8s-46.7,3.9 -46.7,-64.6V470l33,-0.2z"
android:fillColor="#CE4141"/>
<path
android:pathData="M732.1,831.6H267.8c-32.1,0 -58.2,-26.1 -58.2,-58.2v-221.3c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v221.3c0,21 17.1,38.2 38.2,38.2h464.4c21,0 38.2,-17.1 38.2,-38.2V475.3c0,-5.2 4,-9.5 9.1,-10 19.5,-1.7 34.8,-18.4 34.8,-38v-45.1c0,-21 -17.1,-38.2 -38.2,-38.2H223.9c-21,0 -38.2,17.1 -38.2,38.2v45.1c0,19.5 15.1,36 34.3,38h491.3c5.5,0 10,4.5 10,10s-4.5,10 -10,10H219.6c-0.3,0 -0.6,-0 -0.9,-0 -14.4,-1.3 -27.8,-7.9 -37.6,-18.5 -9.9,-10.8 -15.4,-24.7 -15.4,-39.4v-45.1c0,-32.1 26.1,-58.2 58.2,-58.2h552.1c32.1,0 58.2,26.1 58.2,58.2v45.1c0,14.6 -5.5,28.6 -15.4,39.4 -7.7,8.4 -17.6,14.3 -28.5,17v289.7c0,32.1 -26.1,58.2 -58.2,58.2z"
android:fillColor="#333333"/>
<path
android:pathData="M864.9,645.2c28.2,28.2 28.2,74.1 0,102.3l-51.2,51.2 -102.4,-102.4 51.2,-51.2c28.2,-28.2 74.1,-28.2 102.3,0z"
android:fillColor="#B1DCFD"/>
<path
android:pathData="M660.2,849.9c-28.2,-28.2 -28.2,-74.1 0,-102.3l51.2,-51.2 102.4,102.4 -51.2,51.2c-28.2,28.2 -74.1,28.2 -102.3,0z"
android:fillColor="#45A6FC"/>
<path
android:pathData="M799,781.5l-53.8,47.9s-23.5,19.6 -47.9,10.8c0,0 -44.6,-14.2 -53.6,-48.2 0,0 -16.3,54.2 56.8,78.6 0,0 37.9,5.8 71,-29.5l42.3,-43 -14.7,-16.6z"
android:fillColor="#389BE5"/>
<path
android:pathData="M817.9,790l73,-72.2 3.1,-21 -94.9,84.8 18.8,8.4z"
android:fillColor="#89CBF4"/>
<path
android:pathData="M813.7,808.8c-2.6,0 -5.1,-1 -7.1,-2.9l-66.7,-66.7c-3.9,-3.9 -3.9,-10.2 0,-14.1s10.2,-3.9 14.1,0l59.6,59.6 44.1,-44.1c24.3,-24.3 24.3,-63.9 0,-88.2 -24.3,-24.3 -63.9,-24.3 -88.2,0l-51.2,51.2c-3.9,3.9 -10.2,3.9 -14.1,0 -3.9,-3.9 -3.9,-10.2 0,-14.1l51.2,-51.2c32.1,-32.1 84.4,-32.1 116.5,0 32.1,32.1 32.1,84.4 0,116.5l-51.2,51.2a10,10 0,0 1,-7.1 2.9z"
android:fillColor="#333333"/>
<path
android:pathData="M711.4,881.1c-21.1,0 -42.2,-8 -58.3,-24.1 -15.6,-15.6 -24.1,-36.2 -24.1,-58.3s8.6,-42.7 24.1,-58.3l51.2,-51.2c3.9,-3.9 10.2,-3.9 14.1,0 3.9,3.9 3.9,10.2 0,14.1l-51.2,51.2c-11.8,11.8 -18.3,27.4 -18.3,44.1s6.5,32.3 18.3,44.1c24.3,24.3 63.9,24.3 88.2,0l51.2,-51.2c3.9,-3.9 10.2,-3.9 14.1,0s3.9,10.2 0,14.1l-51.2,51.2c-16.1,16.1 -37.2,24.1 -58.3,24.1z"
android:fillColor="#333333"/>
<path
android:pathData="M499.8,648.5m-114.8,0a114.8,114.8 0,1 0,229.5 0,114.8 114.8,0 1,0 -229.5,0Z"
android:fillColor="#FDFBF7"/>
<path
android:pathData="M520.3,578.3m0,12.3l0,116q0,12.3 -12.3,12.3l-16.6,0q-12.3,0 -12.3,-12.3l0,-116q0,-12.3 12.3,-12.3l16.6,0q12.3,0 12.3,12.3Z"
android:fillColor="#EA5959"/>
<path
android:pathData="M570,669.1m-12.3,0l-116,0q-12.3,0 -12.3,-12.3l0,-16.6q0,-12.3 12.3,-12.3l116,0q12.3,0 12.3,12.3l0,16.6q0,12.3 -12.3,12.3Z"
android:fillColor="#EA5959"/>
<path
android:pathData="M649.8,339.7c-5.5,0 -10,-4.5 -10,-10v-39.8c0,-5.1 -4.1,-9.2 -9.2,-9.2H368.4c-5.1,0 -9.2,4.1 -9.2,9.2 0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10c0,-16.1 13.1,-29.2 29.2,-29.2h262.2c16.1,0 29.2,13.1 29.2,29.2v39.8c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M280.8,339.7c-5.5,0 -10,-4.5 -10,-10v-39.8c0,-53.8 43.8,-97.7 97.7,-97.7h262.2c53.8,0 97.7,43.8 97.7,97.7 0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10c0,-42.8 -34.8,-77.7 -77.7,-77.7H368.4c-42.8,0 -77.7,34.8 -77.7,77.7v39.8c0,5.5 -4.5,10 -10,10zM499.8,773.2c-32,0 -63.9,-12.2 -88.2,-36.5 -48.7,-48.7 -48.7,-127.8 0,-176.4 26.8,-26.8 63.9,-39.9 101.7,-35.8 5.5,0.6 9.5,5.5 8.9,11 -0.6,5.5 -5.5,9.5 -11,8.9 -31.7,-3.4 -62.8,7.5 -85.4,30.1 -40.8,40.8 -40.8,107.3 0,148.2 20.4,20.4 47.3,30.6 74.1,30.6 26.8,0 53.7,-10.2 74.1,-30.6 19.8,-19.8 30.7,-46.1 30.7,-74.1s-10.9,-54.3 -30.7,-74.1c-3.9,-3.9 -3.9,-10.2 0,-14.1 3.9,-3.9 10.2,-3.9 14.1,0 23.6,23.6 36.5,54.9 36.5,88.2s-13,64.7 -36.5,88.2c-24.3,24.3 -56.3,36.5 -88.2,36.5z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,51 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M181,418l305.1,360.2c12.4,14.7 35.1,14.7 47.5,0L838.7,418H181z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M495.7,789.6L181,418h213.2l109.4,367.3c1.4,4.8 -4.7,8.1 -7.9,4.3z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M523.3,790.6L838.8,418H625.6L515.9,786.6c-1.3,4.5 4.4,7.6 7.4,4z"
android:fillColor="#FC981C"/>
<path
android:pathData="M394.2,418.2H625.6L509.8,240.8l-115.6,177.4z"
android:fillColor="#FFEBA4"/>
<path
android:pathData="M394.2,418.2l115.6,-177.4H306.6l87.6,177.4z"
android:fillColor="#FBE87D"/>
<path
android:pathData="M625.6,418.2l87.5,-177.4H509.8L625.6,418.2z"
android:fillColor="#FDCD6E"/>
<path
android:pathData="M625.6,418.2h213.1L713.1,240.8 625.6,418.2z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M394.2,418.2H181l125.6,-177.4 87.6,177.4z"
android:fillColor="#FEDB55"/>
<path
android:pathData="M509.8,801a38.5,38.5 0,0 1,-29.4 -13.6L187.7,441.8c-11.4,-13.4 -12.2,-32.8 -2,-47.2l104.3,-147.3c7.2,-10.2 19,-16.3 31.5,-16.3h376.9c12.5,0 24.3,6.1 31.5,16.3l104.3,147.3c10.2,14.4 9.3,33.8 -2,47.2l-51,60.2c-3.6,4.2 -9.9,4.7 -14.1,1.2s-4.7,-9.9 -1.2,-14.1l51,-60.2a18.5,18.5 0,0 0,1 -22.7L713.5,258.8c-3.5,-4.9 -9.1,-7.8 -15.1,-7.8H321.4c-6,0 -11.7,2.9 -15.1,7.8L201.9,406.1a18.6,18.6 0,0 0,1 22.7l292.8,345.6c3.5,4.2 8.7,6.6 14.1,6.6 5.5,0 10.6,-2.4 14.1,-6.6l59.8,-70.6c3.6,-4.2 9.9,-4.7 14.1,-1.2s4.7,9.9 1.2,14.1l-59.8,70.6a38.5,38.5 0,0 1,-29.4 13.6z"
android:fillColor="#333333"/>
<path
android:pathData="M472.2,698.2c-4.3,0 -8.3,-2.8 -9.6,-7.2l-64,-220c-1.5,-5.3 1.5,-10.9 6.8,-12.4 5.3,-1.5 10.9,1.5 12.4,6.8l64,220c1.5,5.3 -1.5,10.9 -6.8,12.4 -0.9,0.3 -1.9,0.4 -2.8,0.4zM545.2,698.2c-0.9,0 -1.9,-0.1 -2.8,-0.4 -5.3,-1.5 -8.4,-7.1 -6.8,-12.4l64,-220c1.5,-5.3 7.1,-8.4 12.4,-6.8 5.3,1.5 8.4,7.1 6.8,12.4l-64,220c-1.3,4.4 -5.3,7.2 -9.6,7.2z"
android:fillColor="#333333"/>
<path
android:pathData="M612.8,572.8m29.8,-5.1l130.7,-22.5q29.8,-5.1 34.9,24.6l29.6,172.1q5.1,29.8 -24.6,34.9l-130.7,22.5q-29.8,5.1 -34.9,-24.6l-29.6,-172.1q-5.1,-29.8 24.6,-34.9Z"
android:fillColor="#EA5959"/>
<path
android:pathData="M614.8,616.4c5,29.1 54.1,45 109.6,35.4 55.5,-9.6 96.4,-40.9 91.4,-70l-2.5,-14.8c-2.5,-14.3 -16.1,-23.9 -30.4,-21.4l-149.2,25.7c-14.3,2.5 -23.9,16.1 -21.4,30.4l2.5,14.8z"
android:fillColor="#CE4141"/>
<path
android:pathData="M677.3,809.7c-8.2,0 -16.2,-2.5 -23.1,-7.4 -8.8,-6.2 -14.6,-15.4 -16.4,-26l-29.6,-172.1c-1.8,-10.6 0.6,-21.2 6.8,-30 6.2,-8.8 15.4,-14.6 26,-16.4L771.6,535.3c10.6,-1.8 21.2,0.6 30,6.8 8.8,6.2 14.6,15.4 16.4,26l14.6,84.8c0.9,5.4 -2.7,10.6 -8.2,11.6 -5.4,0.9 -10.6,-2.7 -11.6,-8.2l-14.6,-84.8c-0.9,-5.3 -3.8,-10 -8.3,-13.1A20.1,20.1 0,0 0,775 555l-130.7,22.5c-5.3,0.9 -10,3.8 -13.1,8.3a20.1,20.1 0,0 0,-3.4 15.1l29.6,172.1c0.9,5.3 3.8,10 8.3,13.1 4.4,3.1 9.8,4.3 15.1,3.4l130.7,-22.5c11,-1.9 18.4,-12.4 16.5,-23.3l-5.2,-30.1c-0.9,-5.4 2.7,-10.6 8.2,-11.6 5.4,-0.9 10.6,2.7 11.6,8.2l5.2,30.1c3.8,21.8 -10.9,42.7 -32.8,46.4l-130.7,22.5c-2.3,0.4 -4.6,0.6 -6.9,0.6z"
android:fillColor="#333333"/>
<path
android:pathData="M723.2,647.7m-40.5,0a40.5,40.5 0,1 0,81 0,40.5 40.5,0 1,0 -81,0Z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M375.2,389.7c-3.7,0 -7.2,-2 -9,-5.6l-48.1,-97.3c-2.5,-4.9 -0.4,-10.9 4.5,-13.4 4.9,-2.5 10.9,-0.4 13.4,4.5l48.1,97.3c2.5,4.9 0.4,10.9 -4.5,13.4 -1.4,0.7 -2.9,1 -4.4,1zM645.1,389.7c-1.5,0 -3,-0.3 -4.4,-1 -4.9,-2.5 -7,-8.4 -4.5,-13.4l48.1,-97.3c2.5,-4.9 8.4,-7 13.4,-4.5 4.9,2.5 7,8.4 4.5,13.4l-48.1,97.3c-1.7,3.5 -5.3,5.6 -9,5.6zM419.3,389.7c-1.9,0 -3.8,-0.5 -5.4,-1.6 -4.6,-3 -5.9,-9.2 -2.9,-13.8l63.4,-97.3c3,-4.6 9.2,-5.9 13.8,-2.9s5.9,9.2 2.9,13.8l-63.4,97.3a10,10 0,0 1,-8.4 4.5zM599.8,389.7a10,10 0,0 1,-8.4 -4.5l-63.4,-97.3c-3,-4.6 -1.7,-10.8 2.9,-13.8 4.6,-3 10.8,-1.7 13.8,2.9l63.4,97.3c3,4.6 1.7,10.8 -2.9,13.8a9.9,9.9 0,0 1,-5.4 1.6z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M861.7,510.2c0,275.1 -72.1,348.7 -347.2,348.7s-345.7,-73.6 -345.7,-348.7S239.3,163 514.5,163s347.2,72.1 347.2,347.2z"
android:fillColor="#D4EFFF"/>
<path
android:pathData="M514.5,869c-73.3,0 -128.1,-5.1 -172.5,-16.1 -47.5,-11.7 -83.7,-30.7 -110.7,-58.1 -26.9,-27.3 -45.5,-63.8 -57,-111.7 -10.6,-44.5 -15.6,-99.4 -15.6,-172.9s5,-128.3 15.6,-172.6c11.5,-47.7 30.1,-84.1 57,-111.2 26.9,-27.1 63.1,-45.9 110.7,-57.5 44.3,-10.8 99.1,-15.9 172.4,-15.9s128.2,5 172.7,15.9c47.7,11.6 84.1,30.4 111.2,57.5 27.1,27.1 45.9,63.5 57.5,111.2 10.8,44.4 15.9,99.3 15.9,172.7 0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10c0,-71.7 -4.9,-125.1 -15.3,-167.9 -10.7,-44 -27.8,-77.3 -52.2,-101.8 -24.4,-24.4 -57.7,-41.5 -101.8,-52.2 -42.8,-10.4 -96.2,-15.3 -167.9,-15.3s-125,4.8 -167.7,15.3c-43.9,10.7 -77,27.8 -101.2,52.2 -24.2,24.4 -41.2,57.7 -51.7,101.8 -10.3,42.8 -15.1,96.1 -15.1,168s4.8,125.3 15.1,168.2c10.6,44.2 27.5,77.7 51.8,102.3 24.3,24.6 57.4,41.9 101.2,52.7 42.8,10.6 96.1,15.5 167.7,15.5 60.9,0 109.5,-3.7 148.8,-11.3 40.9,-7.9 73.1,-20.4 98.3,-38 49.5,-34.6 75.9,-92.2 85.6,-186.8 0.6,-5.5 5.5,-9.5 11,-8.9 5.5,0.6 9.5,5.5 8.9,11 -10.3,100.9 -39.3,162.9 -94.1,201.1 -27.5,19.2 -62.2,32.7 -105.9,41.2 -40.5,7.9 -90.4,11.7 -152.6,11.7z"
android:fillColor="#333333"/>
<path
android:pathData="M334.8,264.1h88.1c36.3,0 65.8,29.5 65.8,65.8v130.6c0,12.9 -10.5,23.4 -23.4,23.4H334.8c-36.3,0 -65.8,-29.5 -65.8,-65.8v-88.1c0,-36.3 29.5,-65.8 65.8,-65.8z"
android:fillColor="#35A5F6"/>
<path
android:pathData="M693.3,483.9H562.7c-12.9,0 -23.4,-10.5 -23.4,-23.4V329.9c0,-36.3 29.5,-65.8 65.8,-65.8h88.1c36.3,0 65.8,29.5 65.8,65.8v88.1c0,36.3 -29.5,65.8 -65.8,65.8z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M334.8,532.3h130.6c12.9,0 23.4,10.5 23.4,23.4v130.6c0,36.3 -29.5,65.8 -65.8,65.8h-88.1c-36.3,0 -65.8,-29.5 -65.8,-65.8v-88.1c0,-36.3 29.5,-65.8 65.8,-65.8z"
android:fillColor="#54D533"/>
<path
android:pathData="M693.3,752.1h-88.1c-36.3,0 -65.8,-29.5 -65.8,-65.8V555.7c0,-12.9 10.5,-23.4 23.4,-23.4h130.6c36.3,0 65.8,29.5 65.8,65.8v88.1c0,36.3 -29.5,65.8 -65.8,65.8z"
android:fillColor="#EA5959"/>
<path
android:pathData="M309,279v134.9S309,444 338,444h146v34.6H316.6S269,472.1 269,425.5s0.8,-100.3 0.8,-100.3S274,279 309,279z"
android:fillColor="#0080E0"/>
<path
android:pathData="M309,541v144.9S309,716 338,716h146c0,19.1 -15.5,34.6 -34.6,34.6H316.6s-47.6,-6.5 -47.6,-53.1 0.8,-100.3 0.8,-100.3S274,541 309,541z"
android:fillColor="#54B721"/>
<path
android:pathData="M579,280v134.9S579,445 608,445h146c0,19.1 -15.5,34.6 -34.6,34.6H568s-29,10.4 -29,-53.1c0,-46.5 0.8,-100.3 0.8,-100.3S544,280 579,280z"
android:fillColor="#FC981C"/>
<path
android:pathData="M578,529v156.9S578,716 607,716h146c0,19.1 -15.5,34.6 -34.6,34.6H597s-59,-9.6 -59,-53.1c0,-46.5 0.8,-122.3 0.8,-122.3S543,529 578,529z"
android:fillColor="#CE4141"/>
<path
android:pathData="M466.1,493.9H332.7c-40.7,0 -73.8,-33.1 -73.8,-73.8v-23c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v23c0,29.6 24.1,53.8 53.8,53.8H466.1c7,0 12.6,-5.7 12.6,-12.6V327.9c0,-29.6 -24.1,-53.8 -53.8,-53.8h-92.3c-29.6,0 -53.8,24.1 -53.8,53.8v21.1c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10v-21.1c0,-40.7 33.1,-73.8 73.8,-73.8h92.3c40.7,0 73.8,33.1 73.8,73.8v133.4c0,18 -14.6,32.6 -32.6,32.6zM695.4,493.9H562c-18,0 -32.6,-14.6 -32.6,-32.6V327.9c0,-40.7 33.1,-73.8 73.8,-73.8h23.9c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-23.9c-29.6,0 -53.8,24.1 -53.8,53.8v133.4c0,7 5.7,12.6 12.6,12.6H695.4c29.6,0 53.8,-24.1 53.8,-53.8v-92.3c0,-29.6 -24.1,-53.8 -53.8,-53.8h-18c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h18c40.7,0 73.8,33.1 73.8,73.8v92.3c0,40.7 -33.1,73.8 -73.8,73.8zM425,762.1h-16.8c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h16.8c29.6,0 53.8,-24.1 53.8,-53.8V554.9c0,-7 -5.7,-12.6 -12.6,-12.6H332.7c-29.6,0 -53.8,24.1 -53.8,53.8v92.3c0,29.6 24.1,53.8 53.8,53.8h20.7c5.5,0 10,4.5 10,10s-4.5,10 -10,10h-20.7c-40.7,0 -73.8,-33.1 -73.8,-73.8v-92.3c0,-40.7 33.1,-73.8 73.8,-73.8h133.4c18,0 32.6,14.6 32.6,32.6v133.4c0,40.7 -33.1,73.8 -73.8,73.8zM695.4,762.1h-92.3c-40.7,0 -73.8,-33.1 -73.8,-73.8V554.9c0,-18 14.6,-32.6 32.6,-32.6h133.4c40.7,0 73.8,33.1 73.8,73.8v22.3c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10v-22.3c0,-29.6 -24.1,-53.8 -53.8,-53.8H562c-7,0 -12.6,5.7 -12.6,12.6v133.4c0,29.6 24.1,53.8 53.8,53.8h92.3c29.6,0 53.8,-24.1 53.8,-53.8v-19.6c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v19.6c0,40.7 -33.1,73.8 -73.8,73.8z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M782,461.7c0,-53.5 -40.8,-97.5 -92.9,-102.6 -7.8,-66.9 -64.6,-118.8 -133.6,-118.8 -36.7,0 -70,14.7 -94.3,38.6 -24.3,-23.9 -57.6,-38.6 -94.3,-38.6 -69,0 -125.8,51.9 -133.6,118.8 -52.2,5.1 -92.9,49.1 -92.9,102.6s38.5,95 88.5,102.1v92.8c0,50.4 40.9,91.3 91.3,91.3h280.6c50.4,0 91.3,-40.9 91.3,-91.3v-92.6c50.8,-6.5 90,-49.8 90,-102.3z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M333.6,614.3c0,18.9 14.2,34.8 33,36.8a873.3,873.3 0,0 0,188.2 0c18.8,-2 33,-17.9 33,-36.8s-2,-120.8 -127.1,-120.8 -127.1,120.8 -127.1,120.8z"
android:fillColor="#FC981C"/>
<path
android:pathData="M678.9,461.7m-43.5,0a43.5,43.5 0,1 0,87 0,43.5 43.5,0 1,0 -87,0Z"
android:fillColor="#FC981C"/>
<path
android:pathData="M555.5,374.8m-63.2,0a63.2,63.2 0,1 0,126.4 0,63.2 63.2,0 1,0 -126.4,0Z"
android:fillColor="#FC981C"/>
<path
android:pathData="M243.6,461.7m-43.5,0a43.5,43.5 0,1 0,87 0,43.5 43.5,0 1,0 -87,0Z"
android:fillColor="#FC981C"/>
<path
android:pathData="M366.9,374.8m-63.2,0a63.2,63.2 0,1 0,126.4 0,63.2 63.2,0 1,0 -126.4,0Z"
android:fillColor="#FC981C"/>
<path
android:pathData="M345.5,239.3s-72.4,48.6 -79.2,124.8c-1,10.7 -8.9,19.5 -19.5,21.7 -27,5.7 -73,22.9 -72.9,74 0,0 -12.9,67.3 74.1,92.3 0,0 11.4,3.8 11.4,20.9V666s1.6,56 46.6,68l-7.3,8.4s-71.8,-21 -71.3,-88.2v-87.8s-89.9,-19.1 -89.9,-112.7c0,0 8.1,-96.6 90.8,-96.6 0,0 11.7,-104.6 117.2,-117.8z"
android:fillColor="#F29816"/>
<path
android:pathData="M475.3,757.9H330.1c-61.7,0 -111.8,-50.2 -111.8,-111.8v-73.4c0,-0.3 -0.2,-0.5 -0.5,-0.6 -24.6,-5.6 -47,-19.5 -62.9,-39.3 -16.2,-20 -25.1,-45.3 -25.1,-71.1s9.6,-52.9 26.9,-73.3c17.2,-20.2 40.9,-33.8 66.9,-38.2 0.1,-0 0.3,-0.2 0.4,-0.5 5.8,-33.1 23.1,-63.3 48.9,-85.2 26,-22.1 59.2,-34.3 93.4,-34.3s67.8,12.3 94,34.7c0.2,0.2 0.5,0.2 0.7,0 26.1,-22.4 59.5,-34.7 94,-34.7s67.4,12.2 93.4,34.3c25.7,21.8 43.1,52.1 48.9,85.2 0.1,0.3 0.2,0.5 0.4,0.5 36.5,6.3 67.6,30.1 83.3,63.8 2.3,5 0.2,11 -4.8,13.3 -5,2.3 -11,0.2 -13.3,-4.8 -12.9,-27.7 -38.5,-47.3 -68.6,-52.5 -8.5,-1.5 -15.2,-8.2 -16.7,-16.8 -5,-28.5 -19.9,-54.5 -42.1,-73.4 -22.4,-19 -51,-29.5 -80.5,-29.5s-58.4,10.6 -80.9,29.9c-7.7,6.6 -19,6.6 -26.7,0 -22.5,-19.3 -51.3,-29.9 -80.9,-29.9s-58.1,10.5 -80.5,29.5c-22.2,18.8 -37.1,44.9 -42.1,73.4 -1.5,8.6 -8.2,15.3 -16.7,16.8 -44.7,7.7 -77.2,46.3 -77.2,91.8 0,21.5 7.2,41.8 20.7,58.5 13.1,16.3 31.5,27.7 51.8,32.3 9.4,2.1 16,10.4 16,20.1v73.4c0,50.6 41.2,91.8 91.8,91.8h145.1c5.5,0 10,4.5 10,10s-4.5,10 -10,10zM635.4,747c-3.7,0 -7.2,-2 -8.9,-5.5 -2.5,-4.9 -0.5,-10.9 4.4,-13.4 31.1,-15.7 50.5,-47.2 50.5,-82v-73.1c0,-9.6 6.9,-18.1 16.3,-20.1 15.4,-3.3 29.9,-10.5 41.8,-21 4.2,-3.6 10.5,-3.2 14.1,0.9 3.6,4.2 3.2,10.5 -0.9,14.1 -14.5,12.7 -32.1,21.5 -50.8,25.5 -0.3,0.1 -0.5,0.3 -0.5,0.6v73.1c0,42.5 -23.6,80.7 -61.5,99.9a10,10 0,0 1,-4.5 1.1z"
android:fillColor="#333333"/>
<path
android:pathData="M875.8,562.4c-11.5,-11.5 -26.8,-16.9 -41.9,-16.1 0.8,-15.1 -4.6,-30.4 -16.1,-41.9 -21.5,-21.5 -56.4,-21.5 -78,0 -21.2,21.2 -21.5,55.3 -1,76.9L633.2,687.1c-21.6,-20.5 -55.7,-20.1 -76.9,1 -21.5,21.5 -21.5,56.4 0,78 11.5,11.5 26.8,16.9 41.9,16.1 -0.8,15.1 4.6,30.4 16.1,41.9 21.5,21.5 56.4,21.5 78,0 21.5,-21.5 21.5,-56.4 0,-78 -0.4,-0.4 -0.7,-0.7 -1.1,-1l105.7,-105.7c0.3,0.4 0.7,0.7 1,1.1 21.5,21.5 56.4,21.5 78,0 21.5,-21.5 21.5,-56.4 0,-78z"
android:fillColor="#FFF6E6"/>
<path
android:pathData="M807.3,505.2s-25.9,-0.7 -42.4,15.8c0,0 -18.9,19 -2.9,49 0,0 13,13 -1,27L648,710s-11,13 -26,4c0,0 -25,-25 -46,-5 0,0 -20,22 -14,53 0,0 -40.3,-34.6 -1.1,-75.8 0,0 40.1,-28.2 68.1,-4.2 0,0 8.5,4.7 14.3,-3.6l93.8,-93.8s-37.3,-58.5 11.4,-87.1c0,0 38.3,-16.1 59,7.7z"
android:fillColor="#FFDCA9"/>
<path
android:pathData="M653.2,850.2c-16.7,0 -33.4,-6.3 -46.1,-19 -10.6,-10.6 -17.1,-24.5 -18.7,-39.2 -14.7,-1.6 -28.6,-8.1 -39.2,-18.7 -12.3,-12.3 -19.1,-28.7 -19.1,-46.1s6.8,-33.8 19.1,-46.1c12.1,-12.1 28.1,-18.9 45.2,-19.1 13.8,-0.2 27,3.9 38,11.7l93,-93c-7.7,-11.1 -11.8,-24.3 -11.7,-38 0.2,-17.1 7,-33.2 19.1,-45.2 12.3,-12.3 28.7,-19.1 46.1,-19.1s33.8,6.8 46.1,19.1c10.6,10.6 17.1,24.5 18.7,39.2 14.7,1.6 28.6,8.1 39.2,18.7 12.3,12.3 19.1,28.7 19.1,46.1s-6.8,33.8 -19.1,46.1c-25.4,25.4 -66.7,25.4 -92.1,0 -3.9,-3.9 -3.9,-10.2 0,-14.1s10.2,-3.9 14.1,0c17.6,17.6 46.2,17.6 63.8,0 8.5,-8.5 13.2,-19.9 13.2,-31.9s-4.7,-23.4 -13.2,-31.9a45.2,45.2 0,0 0,-34.3 -13.1c-2.8,0.2 -5.6,-0.9 -7.6,-2.9s-3.1,-4.8 -2.9,-7.6a45.2,45.2 0,0 0,-13.1 -34.3c-8.5,-8.5 -19.9,-13.2 -31.9,-13.2s-23.4,4.7 -31.9,13.2c-17.4,17.4 -17.8,45.1 -0.9,62.9 3.7,3.9 3.6,10.1 -0.2,13.9L640.2,694.1c-3.8,3.8 -10,3.9 -13.9,0.2 -17.9,-16.9 -45.5,-16.6 -62.9,0.9 -8.5,8.5 -13.2,19.9 -13.2,31.9s4.7,23.4 13.2,31.9a45.2,45.2 0,0 0,34.3 13.1,10 10,0 0,1 7.6,2.9c2,2 3.1,4.8 2.9,7.6a45.2,45.2 0,0 0,13.1 34.3c17.6,17.6 46.2,17.6 63.8,0 8.5,-8.5 13.2,-19.9 13.2,-31.9s-4.7,-23.4 -13.2,-31.9c-0.2,-0.2 -0.3,-0.3 -0.5,-0.5l-0.4,-0.4a10,10 0,0 1,-3.1 -7.2,10 10,0 0,1 3,-7.2c0.4,-0.4 41.9,-41.3 72.8,-71.6 3.9,-3.9 10.3,-3.8 14.1,0.1 3.9,3.9 3.8,10.3 -0.1,14.1 -23.4,23 -52.9,52 -65.9,64.9 8.7,11.3 13.4,25.1 13.4,39.6 0,17.4 -6.8,33.8 -19.1,46.1 -12.7,12.7 -29.4,19 -46.1,19z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,48 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M708.3,806.4H233c-24,0 -43.5,-19.5 -43.5,-43.5v-317.4h562.2V762.9c0,24 -19.5,43.5 -43.5,43.5z"
android:fillColor="#EA5959"/>
<path
android:pathData="M226.4,456V752.9s-1.1,19.3 13.8,19.3h464.2s36.5,-6.1 47.3,-26.3c0,0 2.3,49.3 -46.3,60H240.6s-51,-6.6 -51,-40.8V447.6l36.9,8.3z"
android:fillColor="#CE4141"/>
<path
android:pathData="M468.4,630.2h8.7c40.6,0 73.6,33 73.6,73.6v88.9H394.8v-88.9c0,-40.6 33,-73.6 73.6,-73.6z"
android:fillColor="#FFD9D9"/>
<path
android:pathData="M254,457.7h433.5c66.3,0 116.2,-40.4 138.5,-97.6 2.4,-6.3 -4.8,-12 -11,-9.6a93,93 0,0 1,-34 5.9c-31.3,-0 -61.4,-3.8 -84.1,-25.2 -18.5,-17.4 -31,-52.4 -36,-77 -2,-9.6 -9.9,-17.2 -19.6,-17.2H300.3c-9.8,0 -17.7,7.7 -19.6,17.2 -5,24.6 -17.6,59.7 -36.2,77.1 -22.8,21.5 -53,25.1 -84.4,25a90.9,90.9 0,0 1,-33.3 -5.7c-6.3,-2.3 -13.6,3.4 -11.1,9.7 22.7,57.1 72.8,97.4 138.3,97.4z"
android:fillColor="#FDBC2C"/>
<path
android:pathData="M290.8,254.8S277.9,386 174.5,389c0,0 21.9,31.8 65.6,34.8H718.1s50,-7 95.7,-61.6c0,0 -15.8,69.8 -98.3,93H242.6s-92.1,-2.2 -124.8,-102.8c0,0 68.8,16 97.1,-5 0,0 55.2,-41.9 76,-92.6z"
android:fillColor="#F29816"/>
<path
android:pathData="M687.5,467.7L254,467.7c-33.5,0 -64.9,-10.1 -91.1,-29.2 -24.8,-18.1 -44.3,-43.9 -56.5,-74.5 -2.5,-6.2 -1.1,-13.2 3.7,-18.2 5.2,-5.4 13.1,-7.2 20.1,-4.6a80.6,80.6 0,0 0,29.7 5.1h0.2c27.8,0.1 56.5,-2.5 77.5,-22.3 15.9,-14.9 28.1,-46.8 33.2,-71.8 2.9,-14.6 15.3,-25.2 29.4,-25.2h341c14,0 26.4,10.6 29.4,25.2 5.1,25 17.3,56.9 33.1,71.7 4,3.8 4.2,10.1 0.4,14.1 -3.8,4 -10.1,4.2 -14.1,0.4 -20.3,-19.1 -33.7,-56.2 -39,-82.3 -0.9,-4.6 -4.6,-9.2 -9.8,-9.2L300.3,247c-5.2,0 -8.9,4.6 -9.8,9.2 -5.3,26.1 -18.7,63.4 -39.1,82.5 -26.2,24.6 -60.8,27.8 -91.2,27.7 -11.3,0.2 -22.5,-1.5 -33.2,-5.1 10.9,25.1 27.3,46.1 47.8,61.1 22.7,16.6 50.1,25.4 79.3,25.4h433.5c57,0 104.3,-32.2 127.3,-86.5a102.3,102.3 0,0 1,-33.9 5.2c-9.4,-0 -17.5,-0.4 -24.9,-1.1 -5.5,-0.5 -9.5,-5.4 -9,-10.9 0.5,-5.5 5.4,-9.5 10.9,-9 6.8,0.6 14.3,1 23.1,1h0.2c10.4,0.2 20.6,-1.6 30.4,-5.3 6.8,-2.6 14.7,-0.9 19.9,4.4 4.9,4.9 6.4,11.9 3.9,18.2 -12,30.8 -31.4,56.6 -56.2,74.7 -26.2,19.2 -57.9,29.3 -91.7,29.3zM818.6,359.9h-0,0zM125,356.6v0z"
android:fillColor="#333333"/>
<path
android:pathData="M473,638.7s-47.8,21.4 -47.8,57.4v103.8h-30.2V694.8s18.9,-65.9 77.9,-56.1z"
android:fillColor="#FFC0C0"/>
<path
android:pathData="M639.7,813.7H240.6c-32.4,0 -58.7,-26.3 -58.7,-58.7V496.5c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v258.5c0,21.3 17.4,38.7 38.7,38.7h399.1c5.5,0 10,4.5 10,10s-4.5,10 -10,10zM754.1,527.4c-5.5,0 -10,-4.5 -10,-10v-74.5c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v74.5c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M395.1,800.7c-5.5,0 -10,-4.5 -10,-10v-84.6c0,-48.5 39.5,-88 88,-88S561,657.6 561,706.1v50.2c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10v-50.2c0,-37.5 -30.5,-68 -68,-68s-68,30.5 -68,68v84.6c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M835.3,610.6c-9.3,-9.3 -11,-23.4 -5,-34.5 2.2,-4 1.4,-8.9 -1.8,-12.1l-22.8,-22.8c-4,-4 -10.5,-4 -14.4,0L614.3,718.2c-4,4 -4,10.5 0,14.4l22.8,22.8c3.2,3.2 8.1,3.9 12.1,1.8 11.1,-6 25.1,-4.3 34.5,5 9.3,9.3 11,23.4 5,34.5a10.2,10.2 0,0 0,1.8 12.1l22.8,22.8c4,4 10.5,4 14.4,0l177,-177c4,-4 4,-10.5 0,-14.4l-22.8,-22.8c-3.2,-3.2 -8.1,-3.9 -12.1,-1.8 -11.1,6 -25.1,4.3 -34.5,-5z"
android:fillColor="#FFF6E6"/>
<path
android:pathData="M639.1,703.4l17.4,17.4s25.3,-9.1 47.8,13.3c0,0 24,19.5 20.2,45.7l5.2,5.2 159.9,-159.9 20.9,20.9 -188.3,188.3 -28.7,-28.7s2.5,-25.9 -15.5,-43.9c0,0 -20.4,-21.1 -37.4,-4l-28.6,-28.6 27.1,-25.7z"
android:fillColor="#F8E0BB"/>
<path
android:pathData="M720.4,844.5c-5.4,0 -10.5,-2.1 -14.3,-5.9l-22.8,-22.8c-6.3,-6.3 -7.7,-16.1 -3.5,-23.9 4,-7.4 2.6,-16.7 -3.3,-22.7 -5.9,-5.9 -15.3,-7.3 -22.7,-3.3 -7.8,4.2 -17.6,2.8 -23.9,-3.5l-22.8,-22.8c-7.9,-7.9 -7.9,-20.7 0,-28.6L784.2,534.2c3.8,-3.8 8.9,-5.9 14.3,-5.9s10.5,2.1 14.3,5.9l22.8,22.8c6.3,6.3 7.7,16.1 3.5,23.9 -4,7.4 -2.6,16.7 3.3,22.7 5.9,5.9 15.3,7.3 22.7,3.3 7.8,-4.2 17.6,-2.8 23.9,3.5l22.8,22.8c3.8,3.8 5.9,8.9 5.9,14.3s-2.1,10.5 -5.9,14.3L734.7,838.6a20.1,20.1 0,0 1,-14.3 5.9zM662.9,743.8c10.2,0 20.3,3.9 27.8,11.4 12.2,12.2 14.9,31.2 6.8,46.3 -0,0.1 -0,0.2 0,0.2l22.8,22.8c0.1,0.1 0.3,0.1 0.3,0L897.5,647.5s0.1,-0.1 0.1,-0.2 -0,-0.1 -0.1,-0.2l-22.8,-22.8a0.2,0.2 0,0 0,-0.2 -0c-15.1,8.2 -34.2,5.4 -46.3,-6.8 -12.2,-12.2 -14.9,-31.2 -6.8,-46.3 0,-0.1 0,-0.2 -0,-0.2l-22.8,-22.8c-0.1,-0.1 -0.3,-0.1 -0.3,0L621.4,725.3c-0.1,0.1 -0.1,0.2 0,0.3l22.8,22.8a0.2,0.2 0,0 0,0.2 0c5.8,-3.1 12.2,-4.7 18.5,-4.7z"
android:fillColor="#333333"/>
<path
android:pathData="M740.9,753.8c-2.7,0 -5.4,-1.1 -7.4,-3.3 -4.9,-5.5 -47.5,-54.3 -20.6,-81.2 1.4,-1.4 8.9,-8.1 23.4,-8.3 17.4,-0.3 37.2,9 58.9,27.4a10,10 0,0 1,1.1 14.1,10 10,0 0,1 -14.1,1.1c-37.6,-31.9 -54.1,-21 -55.4,-20 -10.2,10.8 10.4,41.2 21.5,53.4 3.7,4.1 3.4,10.4 -0.7,14.1a9.9,9.9 0,0 1,-6.7 2.6zM727,683.5l-0.1,0.1 0.1,-0.1z"
android:fillColor="#333333"/>
<path
android:pathData="M820.8,673.8c-2.6,0 -5.1,-1 -7.1,-2.9 -16.9,-16.9 -26.6,-18.2 -29.9,-17.9 -2,0.2 -3.4,1 -3.4,1 -0.3,0.4 -0.6,0.8 -1,1.2 -1.4,1.4 -0.3,4.3 -0.3,4.3l-0.1,-0.2 -18.4,7.9c-2.4,-5.5 -4.1,-17 4.2,-25.7 1.9,-2.3 7.4,-7.6 17.5,-8.4 13.5,-1 28.8,6.9 45.6,23.7 3.9,3.9 3.9,10.2 0,14.1a10,10 0,0 1,-7.1 2.9z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,51 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M726.7,707.8H215.4a1637.1,1637.1 0,0 1,0 -434.7h511.3a1637.1,1637.1 0,0 1,0 434.7z"
android:fillColor="#FFEF7B"/>
<path
android:pathData="M726.7,273.1H215.4l-15.4,-74.7c-2.1,-10 5.6,-19.4 15.8,-19.4h510.5c10.2,0 17.9,9.4 15.8,19.4l-15.4,74.7z"
android:fillColor="#F7CA11"/>
<path
android:pathData="M215.4,707.8h511.3l15.4,74.7c2.1,10 -5.6,19.4 -15.8,19.4H215.8c-10.2,0 -17.9,-9.4 -15.8,-19.4l15.4,-74.7z"
android:fillColor="#EAA51B"/>
<path
android:pathData="M616.3,553.5a205.8,205.8 0,0 1,-140.9 2.5,205.8 205.8,0 0,0 -135.3,0.4l-27.5,9.6c-20.1,7.1 -41.1,-7.8 -41.1,-29.1v-33.2c0,-36 22.7,-68.1 56.7,-80l11.8,-4.2a205.8,205.8 0,0 1,135.3 -0.4c45.8,15.8 95.7,14.9 140.9,-2.5l12.5,-4.8c20.2,-7.8 41.9,7.2 41.9,28.8v33.6c0,35.1 -21.6,66.6 -54.4,79.2z"
android:fillColor="#E2433B"/>
<path
android:pathData="M720,283.6H473.2c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h246.8c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M216.7,354.9s14.8,234.6 65.7,286.9c53.9,55.3 301.5,66.2 301.5,66.2l-363.4,-0.9s-48.3,-251.5 -3.9,-352.2z"
android:fillColor="#F7CA11"/>
<path
android:pathData="M348.4,717.9H224.7c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h123.7c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M568,781.5c-8.4,-83.4 24.8,-144 129.7,-158.3 72.9,-9.9 129.8,22.5 161.3,54.7 15.7,16.1 9.5,43.1 -11.6,51 -48,17.9 -128.7,56.7 -162.2,123.2 -7.1,14.1 -23.4,21.1 -38.4,16.2 -30.1,-9.8 -73.4,-33.1 -78.8,-86.8zM676,875"
android:fillColor="#F7B82A"/>
<path
android:pathData="M657.8,861.5s-15.1,-147.3 71.4,-190.7c86.5,-43.4 120.6,-8.6 134.5,28.4 0,0 -69.4,45.9 -100,67.6 -37.7,26.6 -72.6,83.7 -102.1,100.9l-3.7,-6.2zM662.1,867.8"
android:fillColor="#E5A21A"/>
<path
android:pathData="M661.5,870.2s-1.9,-131.9 79.3,-172.6 121.9,-2.3 129.7,14.4c0,0 -72.1,30 -100.8,50.4 -35.4,25 -94.9,91.3 -108.1,107.9zM661.5,870.2"
android:fillColor="#FFE360"/>
<path
android:pathData="M658.6,880.7c-3.7,0 -7.4,-0.5 -11,-1.6 -30.7,-9.3 -83.2,-34.1 -89.5,-96.6 -1.1,-10.6 -5.3,-65.5 16.9,-100.4 3,-4.7 9.1,-6 13.8,-3.1 4.7,3 6,9.1 3.1,13.8 -14.5,22.8 -16.6,61.5 -13.9,87.7 2.7,26.7 17.9,62.1 75.4,79.4 8.6,2.6 17.8,-1.5 21.8,-9.9 15.2,-31.4 41.6,-60 78.6,-84.9 32.1,-21.6 66.2,-36.5 89.2,-45.2 7.1,-2.7 12.1,-8.4 13.7,-15.9 1.6,-7.4 -0.5,-14.7 -5.9,-20.1 -11.9,-12 -32.3,-28.7 -61.5,-40.3 -28.7,-11.3 -59,-14.9 -90.3,-10.6 -5.5,0.8 -10.5,-3.1 -11.3,-8.6 -0.8,-5.5 3.1,-10.5 8.6,-11.3 34.7,-4.7 68.4,-0.8 100.3,11.8 32.5,12.8 55.1,31.4 68.4,44.8 10.1,10.1 14.2,24.5 11.2,38.4 -3,13.9 -12.9,25.3 -26.2,30.3 -45.1,17 -125.5,55.1 -156.9,120.1 -6.6,13.7 -20.2,21.9 -34.6,21.9z"
android:fillColor="#333333"/>
<path
android:pathData="M617.5,536.7a205.8,205.8 0,0 1,-140.9 2.5,205.8 205.8,0 0,0 -135.3,0.4l-27.5,9.6c-20.1,7.1 -41.1,-7.8 -41.1,-29.1v-33.2c0,-36 22.7,-68.1 56.7,-80l11.8,-4.2a205.8,205.8 0,0 1,135.3 -0.4c45.8,15.8 95.7,14.9 140.9,-2.5l12.5,-4.8c20.2,-7.8 41.9,7.2 41.9,28.8v33.6c0,35.1 -21.6,66.6 -54.4,79.2z"
android:fillColor="#F9675A"/>
<path
android:pathData="M473.2,185.8s175.4,9.2 225.6,27.9c0,0 21.1,7.1 21.2,51.9l22.5,-59.4 -4.1,-21.8 -265.2,1.5z"
android:fillColor="#EAA51B"/>
<path
android:pathData="M224.7,716.8s5.6,47 27.1,49.3c0,0 109.6,20.8 268.6,28.8l-308.4,6 -11,-8.9 23.7,-75.2z"
android:fillColor="#D88F0F"/>
<path
android:pathData="M520.8,811.9H217.8c-7.9,0 -15.3,-3.5 -20.3,-9.6s-6.9,-14.1 -5.3,-21.8l15.1,-73a1647.8,1647.8 0,0 1,0 -434l-15.1,-73c-1.6,-7.7 0.3,-15.7 5.3,-21.8s12.4,-9.6 20.3,-9.6h510.5c7.9,0 15.3,3.5 20.3,9.6 5,6.1 6.9,14.1 5.3,21.8l-15.1,73c13.5,101.3 17.5,204.4 11.9,306.4 -0.3,5.5 -5,9.7 -10.5,9.4 -5.5,-0.3 -9.7,-5 -9.4,-10.5 5.5,-101.3 1.5,-203.8 -12,-304.4 -0.2,-1.1 -0.1,-2.3 0.1,-3.3l15.4,-74.7c0.5,-2.5 -0.6,-4.3 -1.3,-5.1 -0.7,-0.9 -2.2,-2.3 -4.8,-2.3H217.8c-2.5,0 -4.1,1.4 -4.8,2.3 -0.7,0.9 -1.8,2.6 -1.3,5.1l15.4,74.7c0.2,1.1 0.3,2.2 0.1,3.3a1627.3,1627.3 0,0 0,0 432c0.2,1.1 0.1,2.3 -0.1,3.3l-15.4,74.7c-0.5,2.5 0.6,4.3 1.3,5.1 0.7,0.9 2.2,2.3 4.8,2.3h303c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,45 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M694.5,402h-61c0,-83.7 -68.1,-151.8 -151.8,-151.8S329.9,318.3 329.9,402h-61c0,-117.3 95.5,-212.8 212.8,-212.8S694.5,284.7 694.5,402zM667.8,811H295.6c-37.2,0 -68.4,-27.9 -72.7,-64.8l-30.2,-264.9h578L740.5,746.2C736.3,783.1 705,811 667.8,811z"
android:fillColor="#35A5F6"/>
<path
android:pathData="M767.8,506H195.6c-22,0 -40.5,-16.5 -43.1,-38.3l-7,-59.6c-2.6,-21.6 14.4,-40.7 36.2,-40.7h600.3c21.8,0 38.7,19 36.2,40.7l-7,59.6c-2.6,21.9 -21.1,38.3 -43.1,38.3z"
android:fillColor="#8FD4FF"/>
<path
android:pathData="M548.8,579.3m38.8,4.1l0,0q38.8,4.1 34.6,42.9l-6.9,64.6q-4.1,38.8 -42.9,34.6l0,0q-38.8,-4.1 -34.6,-42.9l6.9,-64.6q4.1,-38.8 42.9,-34.6Z"
android:fillColor="#FDFBF7"/>
<path
android:pathData="M430.3,721.5m-38.8,4.1l0,0q-38.8,4.1 -42.9,-34.6l-6.9,-64.6q-4.1,-38.8 34.6,-42.9l0,0q38.8,-4.1 42.9,34.6l6.9,64.6q4.1,38.8 -34.6,42.9Z"
android:fillColor="#FDFBF7"/>
<path
android:pathData="M690.9,372.8c-4.7,0 -8.9,-3.4 -9.8,-8.2 -5.4,-29 -16.9,-55.9 -34.1,-80 -3.2,-4.5 -2.2,-10.7 2.3,-13.9 4.5,-3.2 10.7,-2.2 13.9,2.3 18.9,26.5 31.5,56.1 37.4,88 1,5.4 -2.6,10.6 -8,11.7 -0.6,0.1 -1.2,0.2 -1.9,0.2zM272.5,372.9c-0.6,0 -1.2,-0.1 -1.9,-0.2 -5.4,-1 -9,-6.2 -8,-11.7 9.4,-50.4 36.4,-96.5 75.9,-129.7 40,-33.6 90.9,-52.2 143.1,-52.2 48.5,0 94.7,15.4 133.5,44.5 4.4,3.3 5.3,9.6 2,14a10,10 0,0 1,-14 2c-35.3,-26.5 -77.3,-40.5 -121.5,-40.5 -47.5,0 -93.8,16.9 -130.3,47.5 -36,30.3 -60.6,72.2 -69.1,118 -0.9,4.8 -5.1,8.2 -9.8,8.2z"
android:fillColor="#333333"/>
<path
android:pathData="M334.9,373.6c-0.8,0 -1.7,-0.1 -2.5,-0.3 -5.3,-1.4 -8.5,-6.9 -7.1,-12.2 18.6,-71.2 83,-120.8 156.5,-120.8S619.1,289.5 638,360.1c1.4,5.3 -1.7,10.8 -7.1,12.3 -5.3,1.4 -10.8,-1.7 -12.3,-7.1 -16.6,-61.9 -72.9,-105.1 -137,-105.1s-120.9,43.5 -137.2,105.9a10,10 0,0 1,-9.7 7.5zM576.6,735.8c-1.7,0 -3.5,-0.1 -5.2,-0.3 -26.9,-2.9 -46.4,-27 -43.5,-53.9l6.9,-64.6c1.4,-13 7.8,-24.7 17.9,-32.9 10.2,-8.2 23,-12 36,-10.6 26.9,2.9 46.4,27 43.5,53.9l-6.9,64.6a49,49 0,0 1,-48.7 43.8zM583.4,593.2c-6.6,0 -13,2.2 -18.2,6.4 -6,4.9 -9.8,11.8 -10.6,19.5l-6.9,64.6c-1.7,15.9 9.9,30.2 25.8,31.9 6.9,0.7 13.9,-1 19.6,-5a29,29 0,0 0,12.3 -20.8l6.9,-64.6c1.7,-15.9 -9.9,-30.2 -25.8,-31.9 -1,-0.1 -2.1,-0.2 -3.1,-0.2zM387.4,735.8c-11.1,0 -21.9,-3.8 -30.7,-10.9 -10.2,-8.2 -16.5,-19.9 -17.9,-32.9l-6.9,-64.6c-2.9,-26.9 16.7,-51 43.5,-53.9 13,-1.4 25.8,2.4 36,10.6 10.2,8.2 16.5,19.9 17.9,32.9l6.9,64.6c2.9,26.9 -16.7,51 -43.5,53.9 -1.8,0.2 -3.5,0.3 -5.3,0.3zM380.6,593.2c-1,0 -2.1,0.1 -3.1,0.2 -15.9,1.7 -27.5,16 -25.8,31.9l6.9,64.6c0.8,7.7 4.6,14.6 10.6,19.5 6,4.9 13.6,7.1 21.3,6.3 15.9,-1.7 27.5,-16 25.8,-31.9l-6.9,-64.6c-0.8,-7.7 -4.6,-14.6 -10.6,-19.5 -5.2,-4.2 -11.6,-6.4 -18.2,-6.4z"
android:fillColor="#333333"/>
<path
android:pathData="M811.1,469.4l0.9,-7.8H157.4l0.9,7.8c2.6,22.5 21.6,39.4 44.2,39.4h564.5c22.6,0 41.6,-17 44.2,-39.4z"
android:fillColor="#76C1FF"/>
<path
android:pathData="M234.9,512L263,735s7,34 31,34h385.5s39.5,-1 55.5,-27c0,0 4,56.3 -62,64.6H298S238,809 227,748l-30.8,-236h38.7z"
android:fillColor="#0080E0"/>
<path
android:pathData="M667.8,821c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10c32.1,0 59.1,-24.1 62.7,-56l25.8,-226.3c1.3,-11.5 9.3,-20.9 20.4,-24 13.2,-3.6 22.7,-14.7 24.3,-28.3l7,-59.6c0.9,-7.5 -1.5,-15 -6.5,-20.6a26.4,26.4 0,0 0,-19.7 -8.9H181.5a26.4,26.4 0,0 0,-26.2 29.5l7,59.6c2,16.8 16.3,29.5 33.2,29.5h458.9c5.5,0 10,4.5 10,10s-4.5,10 -10,10H195.5c-27.1,-0 -49.9,-20.3 -53,-47.2l-7,-59.6a46.4,46.4 0,0 1,11.4 -36.3,46.4 46.4,0 0,1 34.7,-15.6h600.3a46.4,46.4 0,0 1,34.7 15.6c8.8,9.9 12.9,23.1 11.4,36.3l-7,59.6c-2.6,21.7 -17.8,39.5 -38.8,45.3 -3.1,0.9 -5.4,3.7 -5.8,7l-25.8,226.3c-4.8,42 -40.3,73.7 -82.6,73.7zM594,821H295.6c-42.3,0 -77.8,-31.7 -82.6,-73.7l-20.2,-177.3c-0.6,-5.5 3.3,-10.4 8.8,-11.1 5.5,-0.6 10.4,3.3 11.1,8.8l20.2,177.3c3.6,31.9 30.6,56 62.7,56h298.4c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M842,862H708.3c-30.9,0 -54.8,-27.1 -50.9,-57.7l14.5,-115.2c3.2,-25.6 25,-44.9 50.9,-44.9h104.8c25.9,0 47.7,19.2 50.9,44.9l14.5,115.2c3.8,30.6 -20,57.7 -50.9,57.7z"
android:fillColor="#FEDC5A"/>
<path
android:pathData="M775.1,748.2c-30.5,0 -55.3,-24.8 -55.3,-55.3 0,-5.5 4.5,-10 10,-10s10,4.5 10,10c0,19.5 15.8,35.3 35.3,35.3s35.3,-15.8 35.3,-35.3c0,-5.5 4.5,-10 10,-10s10,4.5 10,10c0,30.5 -24.8,55.3 -55.3,55.3z"
android:fillColor="#333333"/>
<path
android:pathData="M704.2,654.5l-15.3,152.1S683,832.4 711.2,832.4h140.7s25.2,0.6 32.7,-25.8c0,0 9.5,40.4 -35.5,55.4h-140s-50,-9 -52,-51l17.6,-133.2s15.6,-24.8 29.5,-23.3z"
android:fillColor="#FFB236"/>
<path
android:pathData="M812,872H708.3c-17.6,0 -34.3,-7.6 -46,-20.8a61.3,61.3 0,0 1,-14.9 -48.2l14.5,-115.2c3.8,-30.6 30,-53.7 60.8,-53.7h104.8c30.8,0 57,23.1 60.8,53.7l14.5,115.2a61.3,61.3 0,0 1,-34.2 62.9,10 10,0 0,1 -13.4,-4.7 10,10 0,0 1,4.7 -13.4,41.3 41.3,0 0,0 23.1,-42.4l-14.5,-115.2c-2.6,-20.6 -20.2,-36.2 -41,-36.2H722.8c-20.8,0 -38.4,15.5 -41,36.2L667.3,805.6a41.3,41.3 0,0 0,10 32.5,41.3 41.3,0 0,0 31,14h103.7c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,51 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M598.3,275.2l-9.2,-37.8c-1.9,-7.9 -10.3,-18 -20.9,-19.4 -35.7,-4.2 -71.8,-4.2 -107.4,0 -9.6,1.4 -18.8,11.9 -20.9,21.1l-9.1,36.2c55.8,-3.3 111.8,-3.3 167.6,-0z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M234,726m26.6,0l57.8,0q26.6,0 26.6,26.6l0,36.8q0,26.6 -26.6,26.6l-57.8,0q-26.6,0 -26.6,-26.6l0,-36.8q0,-26.6 26.6,-26.6Z"
android:fillColor="#B52828"/>
<path
android:pathData="M348.3,744.4h460.3c10.4,0 18.8,-8.4 18.8,-18.8V616.4h-0.2l-16.1,-99.3c-0.9,-12 -7.7,-22.4 -17.7,-29.2l56.9,-7.2a12.9,12.9 0,0 0,11.3 -12.8V446.2c0,-7.1 -5.8,-12.9 -12.9,-12.9h-65.8c-6.3,0 -11.7,4.6 -12.7,10.9l-23.2,-95.7c-5.9,-24.7 -32.2,-56.3 -65.3,-60.7a1436.7,1436.7 0,0 0,-335.7 0c-30,4.5 -58.9,37.4 -65.3,66l-22.4,88.5a12.9,12.9 0,0 0,-12.1 -8.7H180.3c-7.1,0 -12.9,5.8 -12.9,12.9v21.8c0,6.5 4.8,12 11.3,12.8l55.3,7.1c-9.9,6.8 -16.6,17.2 -17.5,29.1l-16.1,99.2h-0.2v109.2c0,10.4 8.4,18.8 18.8,18.8h129.3z"
android:fillColor="#EA5959"/>
<path
android:pathData="M322.2,471.4c-9.3,0 -16.9,-7.5 -16.9,-16.9 0,-1.1 0.1,-2.3 0.3,-3.4l15.2,-74.3c5.3,-23.8 27.2,-42.4 52.2,-46.2h2.1c92.1,-10.9 185.2,-10.9 277.3,0h-2.1c27.6,3.7 49.4,20.4 54.3,40.9l18.6,79c2.2,9.1 -3.5,18.2 -12.6,20.4 -1.3,0.3 -2.6,0.4 -3.9,0.4h-384.6z"
android:fillColor="#FFD9D9"/>
<path
android:pathData="M322.1,481.4c-14.8,0 -26.9,-12 -26.9,-26.9 0,-1.8 0.2,-3.6 0.5,-5.4L311,374.9c0,-0.1 0,-0.1 0,-0.2 6.1,-27.3 31,-49.5 60.5,-53.9 0.5,-0.1 1,-0.1 1.5,-0.1h1.5a1188.6,1188.6 0,0 1,279 0.1c1,0.1 2,0.4 2.9,0.8 29.3,5.5 52.3,24.2 57.9,47.7l18.6,79c3.4,14.5 -5.6,29 -20,32.4 -2,0.5 -4.1,0.7 -6.2,0.7h-20.8c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h20.8c0.5,0 1.1,-0.1 1.6,-0.2 3.7,-0.9 6,-4.6 5.2,-8.4l-18.6,-78.9c-3.9,-16.5 -22.8,-30.2 -45.9,-33.3a9.2,9.2 0,0 1,-2 -0.5c-89.8,-10.3 -180.9,-10.1 -270.7,0.5 -0.4,0.1 -0.8,0.1 -1.2,0.1h-1.3c-21.2,3.4 -38.9,19.1 -43.2,38.3l-15.2,74.2a7.1,7.1 0,0 0,-0.1 1.4c0,3.8 3.1,6.9 6.9,6.9h302.9c5.5,0 10,4.5 10,10s-4.5,10 -10,10H322.1z"
android:fillColor="#333333"/>
<path
android:pathData="M291,648m-39,0a39,39 0,1 0,78 0,39 39,0 1,0 -78,0Z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M291,697c-27,0 -49,-22 -49,-49s22,-49 49,-49 49,22 49,49 -22,49 -49,49zM291,619c-16,0 -29,13 -29,29s13,29 29,29 29,-13 29,-29 -13,-29 -29,-29zM431.1,285.6c-0.8,0 -1.6,-0.1 -2.5,-0.3 -5.3,-1.4 -8.6,-6.8 -7.2,-12.1l9.1,-36c2.8,-12.1 14.7,-26.5 29.1,-28.7 0.1,-0 0.2,-0 0.3,-0 36.4,-4.3 73.4,-4.3 109.8,0 0.1,0 0.1,0 0.2,0 14.8,2 26.5,15.3 29.3,27l9.2,37.8c1.3,5.4 -2,10.8 -7.3,12.1 -5.4,1.3 -10.8,-2 -12.1,-7.3l-9.2,-37.8c-1,-4.3 -6.4,-11 -12.4,-11.9a449.3,449.3 0,0 0,-104.8 0c-4.8,0.8 -11.2,7.6 -12.5,13.4l-0.1,0.3 -9.1,36.2a10,10 0,0 1,-9.7 7.6z"
android:fillColor="#333333"/>
<path
android:pathData="M252,490.6s-11.9,132.3 -11.9,188.4c0,0 -2.1,28 16.9,28h382.7v38.3H219s-18.8,-1.6 -18.8,-23.9c0,0 -9.2,-242.2 51.8,-230.8z"
android:fillColor="#CE4141"/>
<path
android:pathData="M682,726m26.6,0l57.8,0q26.6,0 26.6,26.6l0,36.8q0,26.6 -26.6,26.6l-57.8,0q-26.6,0 -26.6,-26.6l0,-36.8q0,-26.6 26.6,-26.6Z"
android:fillColor="#CE4141"/>
<path
android:pathData="M326.7,825.2h-71.5c-17.4,0 -31.6,-14.2 -31.6,-31.6v-39.2h-4.6c-15.9,0 -28.8,-12.9 -28.8,-28.8V616.4c0,-1.3 0.3,-2.6 0.7,-3.7l15.7,-96.7c0.6,-7.3 3,-14.2 6.8,-20.5l-35.9,-4.6c-11.4,-1.4 -20,-11.2 -20,-22.7v-21.8c0,-12.6 10.3,-22.9 22.9,-22.9h65.8c1.9,0 4.2,0 6.3,0l18.5,-72.2c7.1,-31.3 38.3,-68.3 73.5,-73.5 0.1,-0 0.2,-0 0.3,-0a1449,1449 0,0 1,338.1 0c0.1,0 0.1,0 0.2,0 36.6,4.9 66.8,39.3 73.7,68.3l18.7,77.2c2.5,-0.1 5.1,-0.1 7.4,-0.2h65.9c12.6,0 22.9,10.3 22.9,22.9v21.8c0,11.5 -8.6,21.3 -20,22.7l-37.4,4.7c3.9,6.3 6.2,13.3 6.8,20.6l3,18.4c0.9,5.4 -2.8,10.6 -8.3,11.5 -5.4,0.9 -10.6,-2.8 -11.5,-8.3l-3.1,-18.8c-0.1,-0.3 -0.1,-0.6 -0.1,-0.9 -0.6,-8.4 -5.5,-16.3 -13.4,-21.7 -3.4,-2.3 -5.1,-6.6 -4.1,-10.6s4.3,-7.1 8.5,-7.6l56.9,-7.2c1.4,-0.2 2.5,-1.4 2.5,-2.8v-21.8c0,-1.6 -1.3,-2.9 -2.9,-2.9h-65.8c-6,0 -14.6,0.5 -14.7,0.5a10,10 0,0 1,-10.3 -7.6l-20.7,-85.3c-4.7,-19.7 -27,-49.1 -56.8,-53.2 -110.5,-13 -222.6,-13 -333.1,0 -21.5,3.3 -50.3,28.8 -56.8,58.3 -0,0.1 -0.1,0.2 -0.1,0.3l-20.5,79.9a10,10 0,0 1,-9.8 7.5s-8.5,-0.1 -14,-0.1H180.3c-1.6,0 -2.9,1.3 -2.9,2.9v21.8a2.9,2.9 0,0 0,2.5 2.8l55.3,7.1c4.1,0.5 7.5,3.5 8.5,7.6s-0.6,8.3 -4.1,10.6c-7.7,5.3 -12.5,13.2 -13.2,21.6 -0,0.3 -0.1,0.6 -0.1,0.9l-16.1,99.2c-0,0.2 -0.1,0.4 -0.1,0.6v107c0,4.8 3.9,8.8 8.8,8.8h14.6c5.5,0 10,4.5 10,10v49.2c0,6.4 5.2,11.6 11.6,11.6h71.5c6.4,0 11.6,-5.2 11.6,-11.6v-16.5c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v16.5c0,17.4 -14.2,31.6 -31.6,31.6zM586,754.4H278c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h308c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M859.8,674.8c1,60.2 -38.7,119.4 -98,158.7 -13.9,9.2 -32.1,9.3 -46,0.1 -58.7,-38.8 -98.2,-97.1 -98.2,-156.5 0,-66.5 53.7,-120.5 120.1,-121.1 66.2,-0.6 121,52.6 122.1,118.8z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M738.7,677m-57,0a57,57 0,1 0,114 0,57 57,0 1,0 -114,0Z"
android:fillColor="#FC981C"/>
<path
android:pathData="M737.5,563.2S656,596 656,664c0,0 -14.5,84.2 82.7,167.1l-15,6.6s-121,-66.9 -104.8,-177.8c0,0 26.1,-111.5 118.7,-96.7z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M738.7,850.5c-9.9,0 -19.8,-2.8 -28.4,-8.6 -64.3,-42.5 -102.6,-104.1 -102.6,-164.9 0,-34.8 13.5,-67.6 38,-92.3 24.5,-24.7 57.2,-38.5 91.9,-38.8h1.1c71.2,0 129.9,57.5 131.1,128.7 0.5,28.1 -7.1,56.3 -22.6,83.8 -2.7,4.8 -8.8,6.5 -13.6,3.8 -4.8,-2.7 -6.5,-8.8 -3.8,-13.6 13.7,-24.3 20.4,-49.1 20,-73.6 -1,-60.6 -51.3,-109.5 -112,-109 -29.5,0.3 -57.2,11.9 -77.9,32.8 -20.8,21 -32.2,48.7 -32.2,78.3 0,26.7 8.8,54.6 25.5,80.6 16.4,25.5 39.9,48.9 68.2,67.6 10.6,7 24.3,7 35,-0.1 15.7,-10.4 30,-22.2 42.5,-35.2 3.8,-4 10.2,-4.1 14.1,-0.3 4,3.8 4.1,10.2 0.3,14.1 -13.5,14 -28.9,26.8 -45.8,38a51.9,51.9 0,0 1,-28.6 8.6z"
android:fillColor="#333333"/>
<path
android:pathData="M740.8,744.9c-36.9,0 -67,-30 -67,-67s30,-67 67,-67c11.8,0 23.4,3.1 33.6,9 4.8,2.8 6.4,8.9 3.6,13.7 -2.8,4.8 -8.9,6.4 -13.7,3.6a47,47 0,0 0,-23.5 -6.3c-25.9,0 -47,21.1 -47,47s21.1,47 47,47 47,-21.1 47,-47c0,-5.4 -0.9,-10.7 -2.7,-15.7 -1.8,-5.2 0.9,-10.9 6.1,-12.8 5.2,-1.8 10.9,0.9 12.8,6.1 2.5,7.2 3.8,14.7 3.8,22.4 0,36.9 -30,67 -67,67z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,48 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M259.7,193.9h456.5c8.5,0 15.4,6.9 15.4,15.4v521.4H202.2v-479.4c0,-31.7 25.8,-57.5 57.5,-57.5z"
android:fillColor="#57B7F9"/>
<path
android:pathData="M259.7,665.9h472v125.7H259.7c-31.7,0 -57.5,-25.8 -57.5,-57.5V723.4c0,-31.7 25.8,-57.5 57.5,-57.5z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M267.1,701.6h453.9c0.7,0 1.2,0.5 1.2,1.2v52.1c0,0.7 -0.5,1.2 -1.2,1.2h-453.9c-15,0 -27.3,-12.2 -27.3,-27.3 0,-15 12.2,-27.3 27.3,-27.3z"
android:fillColor="#A1DCFF"/>
<path
android:pathData="M262.3,193.7v472.3s-55,10.4 -55,38.2V239.3s11.1,-33.6 55,-45.7z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M515.1,801.7H265.1c-40.2,0 -72.9,-32.7 -72.9,-72.9s32.7,-72.9 72.9,-72.9h417.4c5.5,0 10,4.5 10,10s-4.5,10 -10,10H265.1c-29.1,0 -52.9,23.7 -52.9,52.9s23.7,52.9 52.9,52.9h250c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M202.2,741.9c-5.5,0 -10,-4.5 -10,-10V257.9c0,-40.2 32.7,-72.9 72.9,-72.9h452c13.6,0 24.6,11 24.6,24.6v336c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V209.6c0,-2.5 -2.1,-4.6 -4.6,-4.6H265.1c-29.1,0 -52.9,23.7 -52.9,52.9V731.9c0,5.5 -4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M610.3,253.8h-58.6v154.4l58.6,-28.8V253.8z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M610.3,253.8h58.6v154.4l-58.6,-28.8V253.8z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M789.8,646l-43.7,-43.7L568.5,779.9l13.7,73.7 207.6,-207.6z"
android:fillColor="#FFAC3B"/>
<path
android:pathData="M789.8,646l43.7,43.7L655.9,867.3l-73.7,-13.7 207.6,-207.6z"
android:fillColor="#FFD44A"/>
<path
android:pathData="M668.9,418.1c-1.5,0 -3,-0.3 -4.4,-1l-54.2,-26.7 -54.2,26.7a10,10 0,0 1,-14.4 -9L541.7,253.8c0,-5.5 4.5,-10 10,-10h117.2c5.5,0 10,4.5 10,10v154.4a10,10 0,0 1,-4.7 8.5c-1.6,1 -3.5,1.5 -5.3,1.5zM610.3,369.3c1.5,0 3,0.3 4.4,1l44.2,21.7L658.9,263.8L561.7,263.8v128.3l44.2,-21.7c1.4,-0.7 2.9,-1 4.4,-1z"
android:fillColor="#333333"/>
<path
android:pathData="M813.8,573.3l48.7,48.7c10.7,10.7 10.7,28 0,38.7l-29,29 -87.4,-87.4 29,-29c10.7,-10.7 28,-10.7 38.7,0z"
android:fillColor="#F76C69"/>
<path
android:pathData="M640.9,876.8c-0.5,0 -1,0 -1.5,-0l-48.6,-1.6c-16.4,-0.5 -29.6,-13.8 -30.1,-30.1l-1.6,-48.6c-0.4,-13.1 4.6,-25.9 13.9,-35.1L765.4,568.9c13.4,-13.4 35.3,-13.4 48.8,0l52.8,52.8c13.4,13.4 13.4,35.3 0,48.8L674.5,862.9c-8.9,8.9 -21.1,13.9 -33.6,13.9zM789.8,578.8c-3.7,0 -7.4,1.4 -10.2,4.2L587.1,775.5a27.6,27.6 0,0 0,-8 20.3l1.6,48.6c0.2,5.8 4.9,10.6 10.8,10.8l48.6,1.6c7.6,0.2 15,-2.7 20.3,-8l192.5,-192.5c5.6,-5.6 5.6,-14.8 0,-20.5L800,583a14.4,14.4 0,0 0,-10.2 -4.2z"
android:fillColor="#333333"/>
<path
android:pathData="M799.9,666.2c-2.6,0 -5.1,-1 -7.1,-2.9l-48.7,-48.7c-3.9,-3.9 -3.9,-10.2 0,-14.1s10.2,-3.9 14.1,0l48.7,48.7c3.9,3.9 3.9,10.2 0,14.1a10,10 0,0 1,-7.1 2.9z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,39 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M788.2,816.3H255c-49.1,0 -89,-39.8 -89,-89V475.7c0,-49.1 39.8,-89 89,-89h155.7c155.3,0 301.1,74.7 391.9,200.6l0.3,0.4a276.5,276.5 0,0 1,52.2 161.7c0,36.9 -29.9,66.8 -66.8,66.8z"
android:fillColor="#57B7F9"/>
<path
android:pathData="M506.8,396.4s0,88.3 88,163.1c74.1,63 230.3,59.2 230.3,59.2S700.8,413.7 506.8,396.4z"
android:fillColor="#D4EFFF"/>
<path
android:pathData="M817.2,628.7h-0.1c-15.5,-0.1 -56.4,-1.2 -101.1,-9.4 -56.1,-10.3 -99.2,-27.8 -127.8,-52.2 -50.6,-43 -73,-90.6 -82.9,-122.9 -1.6,-5.3 1.4,-10.9 6.6,-12.5 5.3,-1.6 10.9,1.4 12.5,6.6 9.1,29.7 29.8,73.6 76.7,113.5 26,22.1 65.9,38.2 118.5,47.8 43.2,7.9 82.6,8.9 97.6,9.1 5.5,0 10,4.5 9.9,10.1 -0,5.5 -4.5,9.9 -10,9.9z"
android:fillColor="#333333"/>
<path
android:pathData="M384.6,618.8H177.3V501.3h104c42.5,0 82.3,20.4 107.2,54.9l0.1,0.1a75.7,75.7 0,0 1,14.3 44.2c0,10.1 -8.2,18.3 -18.3,18.3z"
android:fillColor="#D4EFFF"/>
<path
android:pathData="M165.5,723.7h688.3s11.2,92.6 -65.6,92.6H247.8s-82.3,-20.5 -82.3,-92.6z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M788.2,826.3H255c-54.6,0 -99,-44.4 -99,-99v-30.5c0,-5.5 4.5,-10 10,-10s10,4.5 10,10v30.5c0,43.5 35.4,79 79,79h533.1c31.3,0 56.8,-25.5 56.8,-56.8 0,-56.3 -17.4,-110.2 -50.3,-155.8l-0.3,-0.4c-43.6,-60.5 -101.8,-110.5 -168.2,-144.5 -66.4,-34 -141,-52 -215.6,-52H255c-43.5,0 -79,35.4 -79,79v142.8c0,5.5 -4.5,10 -10,10s-10,-4.5 -10,-10V475.7c0,-54.6 44.4,-99 99,-99h155.7c77.8,0 155.5,18.7 224.7,54.2s129.8,87.5 175.3,150.6l0.3,0.4C846.3,631 865,688.9 865,749.4c0,42.4 -34.5,76.8 -76.8,76.8z"
android:fillColor="#333333"/>
<path
android:pathData="M754.8,733.7H170.9c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10h583.9c5.5,0 10,4.5 10,10s-4.5,10 -10,10z"
android:fillColor="#333333"/>
<path
android:pathData="M638.2,278.1l120.2,-93.4c1.6,-1.3 3.7,-1.8 5.7,-1.6 14.2,1.6 26.4,2 41.5,5.2 2.4,0.5 3.5,3.4 2,5.3L717.5,310.8l-79.3,-32.6z"
android:fillColor="#A1DCFF"/>
<path
android:pathData="M717.5,311.8l62,27.6c2.1,0.9 4.4,0.8 6.4,-0.3l65,-36.4a9.3,9.3 0,0 1,7.6 -0.7l16.7,5.9a7.7,7.7 0,0 1,3.3 12.3l-52.5,61.8c-15.4,18.4 -48,9 -48,9s-251.8,-69.9 -251.8,-69.9c-45.5,-13.7 -51.3,-23.3 -51.3,-37.3 0,-18.6 37.3,-23.3 37.3,-23.3 8.6,-4.3 27.7,-14.1 54.5,-4.9l71.4,23.6 79.3,32.6z"
android:fillColor="#FFF6DB"/>
<path
android:pathData="M482,271.7L782,369s33.5,8 55.2,0c0,0 -22,30.1 -58.1,21l-281.5,-79.3s-27.6,-10.3 -15.6,-39z"
android:fillColor="#33A1F2"/>
<path
android:pathData="M797.6,402.4h-0.3c-11.3,-0 -20.6,-2.6 -21,-2.8q-251.7,-69.9 -251.8,-69.9c-0.1,-0 -0.1,-0 -0.2,-0.1C480.2,316.4 466,305 466,282.8c0,-24.6 35.1,-31.6 44.3,-33 9.9,-4.9 31.5,-14.7 60.7,-4.7l66.3,21.9 116,-90.2c3.6,-2.8 8.3,-4.1 12.9,-3.6 3.9,0.4 7.7,0.8 11.4,1.1 9.7,0.9 19.7,1.8 31.1,4.2 4.5,1 8.2,4.2 9.8,8.5 1.6,4.3 0.9,9.1 -2,12.7l-64.8,84.2c-3.4,4.4 -9.6,5.2 -14,1.8 -4.4,-3.4 -5.2,-9.6 -1.8,-14l58.1,-75.5c-6.2,-0.9 -12.1,-1.4 -18.2,-2 -3.5,-0.3 -7.2,-0.6 -11,-1.1l-119.5,92.9a10,10 0,0 1,-9.3 1.6l-71.4,-23.6s-0.1,-0 -0.1,-0c-22.5,-7.7 -38,0.1 -46.4,4.2l-0.4,0.2c-1,0.5 -2.1,0.8 -3.2,1 -13.2,1.7 -28.5,7.9 -28.5,13.4 0,6.8 0,14.4 44.1,27.7 5.9,1.6 251.7,69.9 251.7,69.9 0.3,0.1 26.9,7.1 37.7,-5.8l50.4,-59.3 -13.3,-4.7 -64.8,36.2a17.2,17.2 0,0 1,-15.4 0.6l-61.9,-27.6c-5.1,-2.3 -7.3,-8.2 -5.1,-13.2 2.3,-5.1 8.2,-7.3 13.2,-5.1l60.7,27 63.8,-35.7c4.8,-2.7 10.6,-3.2 15.8,-1.4l16.7,5.9c2.1,0.7 3.9,1.8 5.6,3.2 7.5,6.3 8.4,17.5 2,25l-52.5,61.8c-8.2,9.8 -21,14.9 -37.2,14.9zM784.5,329.2h0,-0z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,54 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M440.3,725.9c-74.5,10.3 -168.4,-24 -220.6,-213.7 -50.8,-184.7 3.8,-264.3 151.8,-284.8 147.9,-20.4 221.6,41.5 222.4,233.1 0.8,190.5 -77.5,254.8 -153.7,265.3z"
android:fillColor="#44A00E"/>
<path
android:pathData="M560.4,687.5c-6.1,-44.4 -47.1,-95.4 -47.1,-95.4 -53.7,-66.8 -98.3,-160.8 -108.6,-183.4a7.5,7.5 0,0 0,-7.8 -4.3,7.5 7.5,0 0,0 -6.4,6.3c-3.9,24.6 -21.3,127.2 -54.9,206 0,0 -25.7,60.2 -19.5,104.6 0,0 5.8,123.8 139.1,105.3 133.3,-18.4 105.3,-139.1 105.3,-139.1z"
android:fillColor="#ABEE93"/>
<path
android:pathData="M564.9,725.9c74.5,10.3 168.4,-24 220.6,-213.7 50.8,-184.7 -3.8,-264.3 -151.8,-284.8 -147.9,-20.4 -221.6,41.5 -222.4,233.1 -0.8,190.5 77.5,254.8 153.7,265.3z"
android:fillColor="#54B721"/>
<path
android:pathData="M444.7,687.5c6.1,-44.4 47.1,-95.4 47.1,-95.4 53.7,-66.8 98.3,-160.8 108.6,-183.4a7.5,7.5 0,0 1,7.8 -4.3c3.3,0.4 5.9,3 6.4,6.3 3.9,24.6 21.3,127.2 54.9,206 0,0 25.7,60.2 19.5,104.6 0,0 -5.8,123.8 -139.1,105.3C416.7,808.2 444.7,687.5 444.7,687.5z"
android:fillColor="#ABEE93"/>
<path
android:pathData="M496,710.9c-80.3,0 -174.7,-50 -202.1,-258.2 -26.8,-202.8 42.7,-279 202.1,-279s228.4,76.3 201.3,279C670.3,654.3 578.2,710.9 496,710.9z"
android:fillColor="#54D533"/>
<path
android:pathData="M500.2,840.3c-14.8,0 -28.6,-1.5 -41.3,-4.3 -1.2,0.2 -2.3,0.3 -3.5,0.5 -44.1,6.1 -79.9,-2 -106.4,-24 -39.3,-32.7 -43.6,-84.3 -44,-90.3 -0.6,-4.5 -0.9,-9.3 -1,-14.3 -0.1,-9.1 -3.6,-17.8 -10,-24.5 -35.9,-37.4 -64.6,-94.1 -85,-168.5 -25.9,-94.3 -25.1,-163.7 2.6,-212.1 21,-36.7 57.1,-61.6 110.2,-75.9 5.3,-1.4 10.8,1.7 12.3,7.1 1.4,5.3 -1.7,10.8 -7.1,12.3 -47.8,12.9 -79.8,34.6 -98.1,66.5 -24.9,43.5 -25.1,107.9 -0.7,196.9 19.6,71.2 46.5,125 80.2,159.9 9.9,10.3 15.5,23.9 15.6,38.1 0,4.3 0.3,8.4 0.9,12.2 0,0.3 0.1,0.6 0.1,0.9 0,0.5 2.8,48.2 36.9,76.4 22,18.2 52.5,24.8 90.8,19.5 1.7,-0.2 3.3,-0.5 4.9,-0.8 1.3,-0.2 2.7,-0.2 4,0.2 11.6,2.8 24.5,4.3 38.5,4.3s27.7,-1.5 39.6,-4.5c1.4,-0.3 2.8,-0.4 4.1,-0.2 2.3,0.4 4.4,0.7 6.6,1 38.3,5.3 68.9,-1.3 90.9,-19.6 34.2,-28.4 36.8,-75.8 36.8,-76.3 0,-0.3 0,-0.6 0.1,-0.9 0.5,-3.8 0.8,-7.9 0.9,-12.2 0.1,-14.3 5.7,-27.8 15.6,-38.1 33.6,-34.9 60.6,-88.7 80.2,-159.9 16.1,-58.5 21.4,-105.6 16.3,-144 -4.9,-36.4 -19.2,-64.1 -43.8,-84.8 -4.2,-3.5 -4.8,-9.9 -1.2,-14.1s9.9,-4.8 14.1,-1.2c28.6,24 45.2,55.9 50.7,97.5 5.5,41 -0,90.7 -16.9,151.9 -20.5,74.4 -49.1,131.1 -85,168.5 -6.4,6.6 -9.9,15.3 -10,24.5 -0.1,5 -0.4,9.8 -1,14.3 -0.4,5.9 -4.6,57.6 -44,90.3 -26.5,22 -62.3,30.1 -106.4,24 -1.7,-0.2 -3.4,-0.5 -5.1,-0.8 -12.9,3.1 -27.2,4.6 -42.4,4.6z"
android:fillColor="#333333"/>
<path
android:pathData="M371,252s-35,56 -25,146c0,0 0,118.6 63.5,208.3l-33.9,54.1S323,608 307.3,524c0,0 -74,-234.5 58.9,-322.8 0,0 47.2,-27.2 101,-26.7 0,0 -84.2,38.5 -96.2,77.5z"
android:fillColor="#54B721"/>
<path
android:pathData="M496,720.9c-5.5,0 -10,-4.5 -10,-10s4.5,-10 10,-10c43.9,0 83.3,-17.4 114,-50.3 39.3,-42.1 65.3,-109.2 77.3,-199.2 13.7,-102.6 2.5,-172.9 -34.2,-214.9 -31.1,-35.5 -82.5,-52.8 -157.2,-52.8s-126.3,17.3 -157.6,53c-36.8,42 -48.2,112.3 -34.7,214.8 5.5,42 14.1,79.3 25.6,111 1.9,5.2 -0.8,10.9 -6,12.8 -5.2,1.9 -10.9,-0.8 -12.8,-6 -11.9,-33 -20.9,-71.8 -26.6,-115.2 -14.3,-108.6 -1.4,-184 39.4,-230.6 35.3,-40.2 91.7,-59.8 172.6,-59.8s137.1,19.5 172.2,59.6c40.8,46.6 53.5,122 39,230.7 -12.6,94.2 -40.4,165 -82.6,210.2 -34.6,37.1 -79.1,56.7 -128.6,56.7z"
android:fillColor="#333333"/>
<path
android:pathData="M624.5,707c0,-44.9 -33.7,-100.9 -33.7,-100.9 -44.1,-73.5 -75.4,-172.7 -82.6,-196.6a7.5,7.5 0,0 0,-7.2 -5.3c-3.3,0 -6.2,2.2 -7.2,5.3 -7.2,23.9 -38.4,123.1 -82.6,196.6 0,0 -33.7,56.1 -33.7,100.9 0,0 -11.2,123.4 123.4,123.4s123.4,-123.4 123.4,-123.4z"
android:fillColor="#D8F9CC"/>
<path
android:pathData="M442.3,566.7S399.3,670.9 414,724c0,0 10.3,66.4 99.6,97.2l-25.1,9.2s-111.8,0.1 -112.7,-123.1c0,0 18.7,-105.9 66.4,-140.6z"
android:fillColor="#ABEE93"/>
<path
android:pathData="M499.2,840.6c-44.5,0 -78.9,-12.9 -102.2,-38.4 -34.5,-37.8 -31.7,-89.5 -31.2,-95.4 0.2,-47 33.7,-103.3 35.1,-105.7 44,-73.4 75.7,-174.7 81.6,-194.3 2.2,-7.4 9,-12.4 16.8,-12.4s14.5,5 16.8,12.4c4.3,14.4 16.3,52.5 34,96.3 2.1,5.1 -0.4,10.9 -5.5,13 -5.1,2.1 -10.9,-0.4 -13,-5.5 -15.4,-38.2 -26.6,-72.1 -32.3,-90.3 -11,35.3 -40.5,123.3 -81.2,191 -0.3,0.5 -32.2,54.3 -32.2,95.8 0,0.3 -0,0.6 -0,0.9 -0,0.5 -3.8,48.1 26.1,80.8 19.3,21 48.7,31.7 87.3,31.7s68,-10.7 87.3,-31.7c29.9,-32.7 26.2,-80.3 26.1,-80.8 -0,-0.3 -0,-0.6 -0,-0.9 0,-41.6 -31.9,-95.3 -32.2,-95.8 -2.8,-4.7 -1.3,-10.9 3.4,-13.7s10.9,-1.3 13.7,3.4c1.4,2.4 34.9,58.7 35.1,105.7 0.4,5.9 3.3,57.7 -31.2,95.4 -23.2,25.5 -57.6,38.4 -102.2,38.4z"
android:fillColor="#333333"/>
<path
android:pathData="M703.5,860.6l-59.7,-2.4c-57,-2.3 -101.8,-50.8 -99.5,-107.8l1.1,-28.6c2.3,-57 50.8,-101.8 107.8,-99.5l59.7,2.4c57,2.3 101.8,50.8 99.5,107.8l-1.1,28.6c-2.3,57 -50.8,101.8 -107.8,99.5z"
android:fillColor="#F76C69"/>
<path
android:pathData="M731.9,830.7l-57.3,1.7c-66.1,-2.6 -107.2,-74.1 -104.5,-140.2l0.2,-4.4c0.3,-7.5 1.3,-14.9 2.9,-22 -14.8,19.1 -24,42.8 -25.1,68.6 -2.6,66.1 49.3,122.3 115.3,124.9l31.8,1.3c45.8,1.9 86.9,-22.6 108.7,-59.8 -29.9,17.4 -46.9,30.9 -72,29.9z"
android:fillColor="#E54E4E"/>
<path
android:pathData="M726.1,689.9l13.1,12.9c5.2,5.2 1.6,14.1 -5.7,14.1l-36.6,0.2c-2,0 -3.9,0.7 -5.3,2l-26.8,23.2c-4.4,3.8 -11.2,2 -13.2,-3.5l-7.7,-22a8.2,8.2 0,0 0,-6.2 -5.4l-26.1,-5.2c-7.8,-1.6 -9.1,-12.2 -1.8,-15.6l24.1,-11.2c2.7,-1.2 4.5,-3.8 4.7,-6.7l2.3,-23.1c0.6,-5.8 6.8,-9.2 12,-6.5l31.5,16.2c1.8,0.9 3.8,1.2 5.7,0.7l35.6,-8.4c7.2,-1.7 12.8,6.1 8.9,12.4l-9.7,15.6c-2,3.3 -1.5,7.6 1.2,10.3z"
android:fillColor="#EA5959"/>
<path
android:pathData="M705.9,678.3l23.1,21.1 -41.6,1.9 -25.8,24.2 -10.3,-26.1 -39.1,-6.2 35.3,-18 1.6,-28 32.1,15 40.1,-11.2 -15.4,27.3z"
android:fillColor="#54D533"/>
<path
android:pathData="M695.6,876.9c-1.8,0 -3.7,-0 -5.5,-0.1l-31.8,-1.3c-18.2,-0.7 -35.8,-5 -52.3,-12.8 -15.9,-7.5 -30,-17.9 -42,-30.9 -11.9,-12.9 -21.2,-27.8 -27.4,-44.3 -6.4,-17 -9.3,-34.9 -8.7,-53.2 0.7,-18.2 5,-35.8 12.8,-52.3 7.5,-15.9 17.9,-30 30.9,-42 12.9,-11.9 27.8,-21.2 44.3,-27.4 17,-6.4 34.9,-9.4 53.2,-8.6l31.8,1.3c18.2,0.7 35.8,5 52.3,12.8 15.9,7.5 30,17.9 42,30.9 11.9,12.9 21.2,27.8 27.4,44.3v0c6.4,17 9.3,34.9 8.6,53.2 -0.7,18.2 -5,35.8 -12.8,52.3 -7.5,15.9 -17.9,30 -30.9,42 -12.9,11.9 -27.8,21.2 -44.3,27.4a134.1,134.1 0,0 1,-47.7 8.7zM663.7,624c-13.9,0 -27.6,2.5 -40.6,7.4 -14,5.3 -26.8,13.2 -37.8,23.4 -11.1,10.2 -19.9,22.3 -26.3,35.8 -6.6,14 -10.3,29 -10.9,44.5 -0.6,15.6 1.9,30.8 7.4,45.3 5.3,14 13.2,26.8 23.4,37.8 10.2,11.1 22.3,19.9 35.8,26.4 14,6.6 29,10.3 44.5,10.9l31.8,1.3c1.5,0.1 3.1,0.1 4.7,0.1 13.9,0 27.6,-2.5 40.6,-7.4 14,-5.3 26.8,-13.2 37.8,-23.4 11.1,-10.2 19.9,-22.3 26.3,-35.8 6.6,-14 10.3,-29 10.9,-44.5 0.6,-15.5 -1.9,-30.8 -7.4,-45.3 -5.3,-14 -13.2,-26.7 -23.4,-37.8 -10.2,-11.1 -22.3,-19.9 -35.8,-26.4 -14,-6.6 -29,-10.3 -44.5,-10.9l-31.8,-1.3c-1.5,-0.1 -3.1,-0.1 -4.7,-0.1zM662.3,733.4a10,10 0,0 1,-9.4 -6.6l-6.9,-19.1 -30.5,-5.7a10,10 0,0 1,-8.1 -8.5c-0.6,-4.3 1.7,-8.5 5.6,-10.3l28.1,-13.4 1.8,-20.3a10,10 0,0 1,14.4 -8.1l26.1,13.1 34,-8.4c3.9,-1 8.1,0.5 10.5,3.8s2.6,7.6 0.5,11.1l-10.9,18.1 15.2,14.7a10,10 0,0 1,2.3 10.9,10 10,0 0,1 -9.1,6.3l-35,0.6 -21.8,19.4a10,10 0,0 1,-6.6 2.5zM649.3,687.9l6,1.1a10,10 0,0 1,7.6 6.4l3.8,10.6 13.6,-12.1a10,10 0,0 1,6.5 -2.5l14.6,-0.3 -3.6,-3.5a10,10 0,0 1,-1.6 -12.4l2.6,-4.3 -14.1,3.5c-2.3,0.6 -4.8,0.3 -6.9,-0.8l-16.2,-8.1 -1,11.3c-0.3,3.5 -2.5,6.6 -5.7,8.2l-5.5,2.6z"
android:fillColor="#333333"/>
</vector>

View File

@@ -0,0 +1,60 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M653,727.5c-2.9,0 -5.8,-0.8 -8.4,-2.5 -7.1,-4.6 -9.1,-14.1 -4.4,-21.2 14.3,-21.9 48,-43.7 69.3,-49.6 8.1,-2.2 16.6,2.5 18.8,10.7s-2.5,16.6 -10.7,18.8c-15.2,4.2 -42.1,22 -51.8,36.8 -2.9,4.5 -7.8,7 -12.8,7z"
android:fillColor="#F5C73E"/>
<path
android:pathData="M635.5,750.3c-4.6,0 -9.2,-2.1 -12.2,-6.1 -5.1,-6.8 -3.7,-16.3 3,-21.4 30.8,-23.2 69.1,-30.4 92.6,-29.5 8.4,0.3 15,7.4 14.7,15.9 -0.3,8.4 -7.4,15.1 -15.9,14.7 -19.2,-0.7 -50.3,6.3 -73,23.4 -2.8,2 -6,3 -9.2,3z"
android:fillColor="#F5C73E"/>
<path
android:pathData="M629.3,906.1H394.7l-77.9,-74c23.4,-89.3 83.4,-130.1 83.4,-130.1h223.7s59.9,40.8 83.4,130.1l-78,74z"
android:fillColor="#64C4F6"/>
<path
android:pathData="M394.7,827.1v79h-87.2c0,-27.6 3.5,-57.2 9.3,-79h77.9zM716.5,906.1h-87.2v-79h77.9c5.7,21.8 9.3,51.4 9.3,79z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M628.7,700.6c64.7,102.9 -28.9,155.3 -116.7,155.3s-181.4,-52.3 -116.7,-155.3h233.4z"
android:fillColor="#99D37A"/>
<path
android:pathData="M512,878.5c-56,0 -122.2,-19.9 -149.3,-68.9 -13.4,-24.2 -21.9,-64.9 13.4,-121.1 6.7,-10.6 20.6,-13.8 31.2,-7.1s13.8,20.6 7.1,31.2c-18.9,30.1 -23,55.3 -12.1,75.1 15,27.2 59.1,45.5 109.6,45.5s94.6,-18.3 109.6,-45.5c10.9,-19.7 6.8,-45 -12.1,-75.1 -6.7,-10.6 -3.5,-24.6 7.1,-31.2 10.6,-6.7 24.6,-3.5 31.2,7.1 35.3,56.2 26.8,96.9 13.4,121.1 -26.9,49 -93.2,68.9 -149.1,68.9z"
android:fillColor="#FCE170"/>
<path
android:pathData="M249.7,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M774.3,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M512,459.5m-269.3,0a269.3,269.3 0,1 0,538.6 0,269.3 269.3,0 1,0 -538.6,0Z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M509.3,265c-14,3 -27.8,-5.8 -30.8,-19.8s5.8,-27.7 19.8,-30.8c26,-5.6 37.7,-30.6 17,-56.4 -8.9,-11.2 -7.1,-27.5 4.1,-36.4 11.2,-8.9 27.5,-7.1 36.4,4.1 44.5,55.7 17,125.4 -46.5,139.3z"
android:fillColor="#47515E"/>
<path
android:pathData="M560,670.9h-96c-44.1,0 -80,-32.3 -80,-72s35.9,-72 80,-72h2.4l2,1.3c26.4,17.6 60.8,17.6 87.1,0l2,-1.3h2.4c44.1,0 80,32.3 80,72s-35.8,72 -79.9,72z"
android:fillColor="#4EAEE0"/>
<path
android:pathData="M543.3,750.9h-62.7c-22.1,0 -40,-17.9 -40,-40 0,-1 0,-2.1 0.1,-3.1l2.9,-37.7c2.9,-37.7 35.9,-65.9 73.6,-63 33.6,2.6 60.4,29.3 63,63l2.9,37.7c1.7,22 -14.8,41.3 -36.8,43 -0.9,0 -1.9,0.1 -3,0.1zM512,622.9c-27.4,0.1 -50.1,21.2 -52.3,48.5l-2.9,37.7c-1,13.2 8.9,24.8 22.1,25.8 0.6,0 1.2,0.1 1.9,0.1h62.7c13.3,0 24,-10.7 24,-24 0,-0.6 0,-1.2 -0.1,-1.9l-2.9,-37.7c-2.4,-27.4 -25.1,-48.4 -52.5,-48.5z"
android:fillColor="#64C4F6"/>
<path
android:pathData="M512,622.9m-48,0a48,48 0,1 0,96 0,48 48,0 1,0 -96,0Z"
android:fillColor="#64C4F6"/>
<path
android:pathData="M600,582.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#64C4F6"/>
<path
android:pathData="M600,614.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#64C4F6"/>
<path
android:pathData="M424,582.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#64C4F6"/>
<path
android:pathData="M424,614.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#64C4F6"/>
<path
android:pathData="M436.3,516.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7zM587.7,516.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7z"
android:fillColor="#450064"/>
</vector>

View File

@@ -0,0 +1,72 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M653,727.5c-2.9,0 -5.8,-0.8 -8.4,-2.5 -7.1,-4.6 -9.1,-14.1 -4.4,-21.2 14.3,-21.9 48,-43.7 69.3,-49.6 8.1,-2.2 16.6,2.5 18.8,10.7s-2.5,16.6 -10.7,18.8c-15.2,4.2 -42.1,22 -51.8,36.8 -2.9,4.5 -7.8,7 -12.8,7z"
android:fillColor="#F5C73E"/>
<path
android:pathData="M635.5,750.3c-4.6,0 -9.2,-2.1 -12.2,-6.1 -5.1,-6.8 -3.7,-16.3 3,-21.4 30.8,-23.2 69.1,-30.4 92.6,-29.5 8.4,0.3 15,7.4 14.7,15.9 -0.3,8.4 -7.4,15.1 -15.9,14.7 -19.2,-0.7 -50.3,6.3 -73,23.4 -2.8,2 -6,3 -9.2,3z"
android:fillColor="#F5C73E"/>
<path
android:pathData="M629.3,906.1H394.7l-77.9,-74c23.4,-89.3 83.4,-130.1 83.4,-130.1h223.7s59.9,40.8 83.4,130.1l-78,74z"
android:fillColor="#F7867F"/>
<path
android:pathData="M394.7,827.1v79h-87.2c0,-27.6 3.5,-57.2 9.3,-79h77.9zM716.5,906.1h-87.2v-79h77.9c5.7,21.8 9.3,51.4 9.3,79z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M628.7,700.6c64.7,102.9 -28.9,155.3 -116.7,155.3s-181.4,-52.3 -116.7,-155.3h233.4z"
android:fillColor="#99D37A"/>
<path
android:pathData="M512,878.5c-56,0 -122.2,-19.9 -149.3,-68.9 -13.4,-24.2 -21.9,-64.9 13.4,-121.1 6.7,-10.6 20.6,-13.8 31.2,-7.1s13.8,20.6 7.1,31.2c-18.9,30.1 -23,55.3 -12.1,75.1 15,27.2 59.1,45.5 109.6,45.5s94.6,-18.3 109.6,-45.5c10.9,-19.7 6.8,-45 -12.1,-75.1 -6.7,-10.6 -3.5,-24.6 7.1,-31.2 10.6,-6.7 24.6,-3.5 31.2,7.1 35.3,56.2 26.8,96.9 13.4,121.1 -26.9,49 -93.2,68.9 -149.1,68.9z"
android:fillColor="#FCE170"/>
<path
android:pathData="M249.7,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M774.3,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M512,459.5m-269.3,0a269.3,269.3 0,1 0,538.6 0,269.3 269.3,0 1,0 -538.6,0Z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M326.5,558.2a49.8,39.5 0,1 0,99.6 0,49.8 39.5,0 1,0 -99.6,0Z"
android:fillColor="#FFD7DF"/>
<path
android:pathData="M597.9,558.2a49.8,39.5 0,1 0,99.6 0,49.8 39.5,0 1,0 -99.6,0Z"
android:fillColor="#FFD7DF"/>
<path
android:pathData="M509.3,265c-14,3 -27.8,-5.8 -30.8,-19.8s5.8,-27.7 19.8,-30.8c26,-5.6 37.7,-30.6 17,-56.4 -8.9,-11.2 -7.1,-27.5 4.1,-36.4 11.2,-8.9 27.5,-7.1 36.4,4.1 44.5,55.7 17,125.4 -46.5,139.3z"
android:fillColor="#47515E"/>
<path
android:pathData="M560,670.9h-96c-44.1,0 -80,-32.3 -80,-72s35.9,-72 80,-72h2.4l2,1.3c26.4,17.6 60.8,17.6 87.1,0l2,-1.3h2.4c44.1,0 80,32.3 80,72s-35.8,72 -79.9,72z"
android:fillColor="#E96E67"/>
<path
android:pathData="M543.3,750.9h-62.7c-22.1,0 -40,-17.9 -40,-40 0,-1 0,-2.1 0.1,-3.1l2.9,-37.7c2.9,-37.7 35.9,-65.9 73.6,-63 33.6,2.6 60.4,29.3 63,63l2.9,37.7c1.7,22 -14.8,41.3 -36.8,43 -0.9,0 -1.9,0.1 -3,0.1zM512,622.9c-27.4,0.1 -50.1,21.2 -52.3,48.5l-2.9,37.7c-1,13.2 8.9,24.8 22.1,25.8 0.6,0 1.2,0.1 1.9,0.1h62.7c13.3,0 24,-10.7 24,-24 0,-0.6 0,-1.2 -0.1,-1.9l-2.9,-37.7c-2.4,-27.4 -25.1,-48.4 -52.5,-48.5z"
android:fillColor="#F7867F"/>
<path
android:pathData="M512,622.9m-48,0a48,48 0,1 0,96 0,48 48,0 1,0 -96,0Z"
android:fillColor="#F7867F"/>
<path
android:pathData="M600,582.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#F7867F"/>
<path
android:pathData="M600,614.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#F7867F"/>
<path
android:pathData="M424,582.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#F7867F"/>
<path
android:pathData="M424,614.9m-8,0a8,8 0,1 0,16 0,8 8,0 1,0 -16,0Z"
android:fillColor="#F7867F"/>
<path
android:pathData="M582,302.8c-3,0 -6,-0.5 -8.9,-1.6L512,279l-61.1,22.2c-13.5,4.9 -28.4,-2.1 -33.3,-15.5 -1,-2.8 -1.6,-5.9 -1.6,-8.9v-60.6c0,-14.4 11.6,-26 26,-26 3,0 6,0.5 8.9,1.6L512,214l61.1,-22.2c13.5,-4.9 28.4,2.1 33.3,15.5 1,2.8 1.6,5.9 1.6,8.9v60.6c0,14.4 -11.6,26 -26,26z"
android:fillColor="#F5C73E"/>
<path
android:pathData="M512,286.5c-13.2,0 -24,-10.8 -24,-24v-32c0,-13.3 10.7,-24 24,-24s24,10.7 24,24v32c0,13.3 -10.8,24 -24,24z"
android:fillColor="#FCE170"/>
<path
android:pathData="M436.3,516.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7zM587.7,516.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7z"
android:fillColor="#450064"/>
</vector>

View File

@@ -0,0 +1,48 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M629.3,906.1H394.7l-77.9,-74c23.4,-89.3 83.4,-130.1 83.4,-130.1h223.7s59.9,40.8 83.4,130.1l-78,74z"
android:fillColor="#99D37A"/>
<path
android:pathData="M394.7,827.1v79h-87.2c0,-27.6 3.5,-57.2 9.3,-79h77.9zM716.5,906.1h-87.2v-79h77.9c5.7,21.8 9.3,51.4 9.3,79z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M438.4,707.7a73.6,47.4 0,1 0,147.2 0,73.6 47.4,0 1,0 -147.2,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M507.3,720l-0.3,0.5 -0.3,-0.5h0.3z"
android:fillColor="#EFEAEB"/>
<path
android:pathData="M507.3,720l-0.3,0.5 -0.3,-0.5h0.3z"
android:fillColor="#EFEAEB"/>
<path
android:pathData="M507.3,720l-0.3,0.5 -0.3,-0.5h0.3z"
android:fillColor="#EFEAEB"/>
<path
android:pathData="M507.3,720l-0.3,0.5 -0.3,-0.5h0.3z"
android:fillColor="#EFEAEB"/>
<path
android:pathData="M249.7,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M774.3,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M512,459.5m-269.3,0a269.3,269.3 0,1 0,538.6 0,269.3 269.3,0 1,0 -538.6,0Z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M436.3,526.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7zM587.7,526.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7zM512,597.7c-16.4,0 -31.9,-7.1 -42.7,-19.4 -4.6,-5.3 -4,-13.3 1.2,-17.9 5.3,-4.6 13.3,-4 17.9,1.2 6,6.8 14.6,10.8 23.6,10.8s17.6,-3.9 23.6,-10.7c4.6,-5.3 12.6,-5.8 17.9,-1.2 5.3,4.6 5.8,12.6 1.2,17.9 -10.8,12.2 -26.3,19.3 -42.7,19.3z"
android:fillColor="#450064"/>
<path
android:pathData="M812.6,394c-4.1,0.1 -8.3,0.2 -12.4,0.2 -83.8,0 -162.2,-23.1 -229.1,-63.4 -69.3,44.5 -151.8,70.4 -240.4,70.4 -40.9,0 -80.6,-5.5 -118.3,-15.9 11,-87.8 60.1,-164.1 130.1,-211.9C390.9,140.3 449.3,121 512,121s121,19.4 169.4,52.4c15.7,10.7 30.4,22.9 43.8,36.3 48.4,48.3 80.5,112.7 87.4,184.3z"
android:fillColor="#5C6A7C"/>
<path
android:pathData="M342.6,328.1c0,10.3 -4.2,19.6 -11,26.4s-16.1,11 -26.4,11H121.9c-20.5,0 -37.3,-16.8 -37.3,-37.3 0,-10.3 4.2,-19.6 11,-26.4s16.1,-11 26.4,-11h183.4c20.4,0 37.2,16.8 37.2,37.3z"
android:fillColor="#4EAEE0"/>
<path
android:pathData="M807,287.7C779.9,149.5 658.1,45.2 512,45.2S244.1,149.5 217,287.7c-3.7,18.8 -5.6,38.2 -5.6,58.1 0,3.6 0.1,7.1 0.2,10.6 0.2,5.1 4.3,9.1 9.4,9.1h582c5.1,0 9.2,-4 9.4,-9.1 0.1,-3.5 0.2,-7.1 0.2,-10.6 0,-19.9 -1.9,-39.3 -5.6,-58.1zM583.1,306.7c-4.1,4.1 -9.7,6.6 -15.9,6.6L456.8,313.3c-12.4,0 -22.5,-10.1 -22.5,-22.5 0,-6.2 2.5,-11.8 6.6,-15.9s9.7,-6.6 15.9,-6.6h110.4c12.4,0 22.5,10.1 22.5,22.5 0,6.2 -2.5,11.8 -6.6,15.9z"
android:fillColor="#64C4F6"/>
</vector>

View File

@@ -0,0 +1,54 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M903.5,836.3c0,23.5 -0.6,46.7 -1.6,69.8H122.1c-1,-22.9 -1.6,-46.3 -1.6,-69.8C120.5,415.9 295.8,75 512,75s391.5,340.9 391.5,761.3z"
android:fillColor="#F3F3F3"/>
<path
android:pathData="M181.8,906c0,-414.3 95.2,-833.6 265.1,-833.6 0,0 19.6,-34.4 65.1,-34.4s65.1,34.4 65.1,34.4c201.7,0 265.1,419.3 265.1,833.6H181.8z"
android:fillColor="#DEE3E3"/>
<path
android:pathData="M548.6,50.4c-12.6,-5.7 -26.6,-8.9 -41.3,-8.9 -55.5,0 -100.4,45 -100.4,100.4s45,100.4 100.4,100.4c14.7,0 28.7,-3.2 41.3,-8.9 34.8,-15.8 59.1,-50.8 59.1,-91.5s-24.2,-75.8 -59.1,-91.5z"
android:fillColor="#47515E"/>
<path
android:pathData="M707.3,832.1l-78,74H394.7l-77.9,-74c2,-7.7 4.3,-15 6.8,-22 26.5,-74 76.6,-108.1 76.6,-108.1h223.7s50,34.1 76.6,108.1c2.5,7 4.8,14.3 6.8,22z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M707.3,832.1l-78,74H394.7l-77.9,-74c2,-7.7 4.3,-15 6.8,-22h376.8c2.6,7 4.9,14.3 6.9,22z"
android:fillColor="#E96E67"/>
<path
android:pathData="M394.7,827.1v79h-87.2c0,-27.6 3.5,-57.2 9.3,-79h77.9zM716.5,906.1h-87.2v-79h77.9c5.7,21.8 9.3,51.4 9.3,79z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M249.7,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M774.3,470.5m-76.8,0a76.8,76.8 0,1 0,153.6 0,76.8 76.8,0 1,0 -153.6,0Z"
android:fillColor="#F7DBD0"/>
<path
android:pathData="M512,459.5m-269.3,0a269.3,269.3 0,1 0,538.6 0,269.3 269.3,0 1,0 -538.6,0Z"
android:fillColor="#FFECE3"/>
<path
android:pathData="M813.6,407.5c-113.6,-0.1 -218.4,-38.2 -302.2,-102.3 -83.5,63.9 -187.8,101.9 -300.9,102.3 5.7,-112.3 72.7,-208.3 168.2,-255.4 40.2,-19.8 85.5,-31 133.4,-31 47.5,0 92.4,11 132.4,30.5 96,46.8 163.4,143.2 169.1,255.9z"
android:fillColor="#5C6A7C"/>
<path
android:pathData="M704.9,827.1H319.7c-4.2,0 -7,-4.4 -5.1,-8.2l34.5,-71.7c0.9,-2 2.9,-3.2 5.1,-3.2h316.3c2.2,0 4.2,1.3 5.1,3.2l34.5,71.7c1.8,3.8 -1,8.2 -5.2,8.2z"
android:fillColor="#F7867F"/>
<path
android:pathData="M326.5,558.2a49.8,39.5 0,1 0,99.6 0,49.8 39.5,0 1,0 -99.6,0Z"
android:fillColor="#FFD7DF"/>
<path
android:pathData="M597.9,558.2a49.8,39.5 0,1 0,99.6 0,49.8 39.5,0 1,0 -99.6,0Z"
android:fillColor="#FFD7DF"/>
<path
android:pathData="M436.3,526.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7zM587.7,526.3c-7,0 -12.7,-5.7 -12.7,-12.7v-10.2c0,-7 5.7,-12.7 12.7,-12.7s12.7,5.7 12.7,12.7v10.2c0,7.1 -5.7,12.7 -12.7,12.7zM512,597.7c-16.4,0 -31.9,-7.1 -42.7,-19.4 -4.6,-5.3 -4,-13.3 1.2,-17.9 5.3,-4.6 13.3,-4 17.9,1.2 6,6.8 14.6,10.8 23.6,10.8s17.6,-3.9 23.6,-10.7c4.6,-5.3 12.6,-5.8 17.9,-1.2 5.3,4.6 5.8,12.6 1.2,17.9 -10.8,12.2 -26.3,19.3 -42.7,19.3z"
android:fillColor="#450064"/>
<path
android:pathData="M606.2,94.4l-20.8,54.5H435l-21,-55 0.8,-0.5c13.2,22 24.6,34.7 33,29.9 14.5,-8.1 13.9,-25.3 13.5,-42.4h0.7c8.3,19 16.7,36.4 27.2,35 18.1,-2.3 19,-31.3 20.8,-57.8h0.8c1.7,26.5 2.7,55.6 20.8,57.8 6.2,0.8 11.6,-4.9 16.9,-13.5 3.6,-6.1 7,-13.6 10.5,-21.5l0.7,0.1c-0.4,17.1 -1,34.3 13.5,42.5 8.4,4.8 19.6,-7.7 32.7,-29.2l0.3,0.1z"
android:fillColor="#FCE170"/>
<path
android:pathData="M606.2,94.4c0.7,0.2 1.3,0.3 2.1,0.3 4.4,0 7.9,-3.6 7.9,-8 0.1,-4.4 -3.5,-8 -7.8,-8 -4.4,0 -7.9,3.6 -7.9,8 0,3.3 2.1,6.2 5,7.4M414.6,93.3c2.2,-1.4 3.6,-3.9 3.6,-6.8 0,-4.5 -3.5,-8 -7.9,-8s-7.8,3.7 -7.8,8.1c0,4.5 3.5,8 7.9,8 1.2,0 2.5,-0.3 3.5,-0.9M461.8,81c5,-0.6 9,-5 9,-10.2 0,-5.7 -4.5,-10.3 -10.1,-10.3 -5.5,0 -10.1,4.6 -10.1,10.3s4.5,10.3 10.1,10.3h0.4M510.6,58.1c6.9,-0.2 12.4,-5.8 12.4,-12.8s-5.7,-12.8 -12.8,-12.8c-7.1,0 -12.8,5.7 -12.8,12.8 0,6.9 5.5,12.6 12.4,12.8M559.3,81c0.4,0 0.7,0.1 1,0.1 5.5,0 10.1,-4.6 10.1,-10.3s-4.4,-10.3 -10.1,-10.3c-5.6,0 -10.1,4.6 -10.1,10.3 0,5 3.6,9.3 8.4,10.1"
android:fillColor="#FCE170"/>
</vector>

View File

@@ -0,0 +1,120 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M966.8,623.5l-0.4,97.9L513.3,984.6l0.4,-97.9 453,-263.3z"
android:fillColor="#3DB542"/>
<path
android:pathData="M690.8,783.9v97.6l275.5,-160.1 0.4,-97.9 -276,160.4z"
android:fillColor="#6DCB60"/>
<path
android:pathData="M860.4,685.3v97.6l106,-61.6 0.4,-97.9 -106.4,61.9z"
android:fillColor="#3DB542"/>
<path
android:pathData="M513.8,886.8l-0.4,97.9L57.2,721.3l0.4,-97.8 456.2,263.4z"
android:fillColor="#6DCB60"/>
<path
android:pathData="M194.2,702.2v98.1l319.2,184.3 0.4,-97.8 -319.6,-184.5z"
android:fillColor="#3DB542"/>
<path
android:pathData="M361.1,798.6v98.1l152.3,87.9 0.4,-97.9 -152.7,-88.2z"
android:fillColor="#6DCB60"/>
<path
android:pathData="M966.8,623.5L513.8,886.8 57.6,623.4l453,-263.3 456.2,263.4z"
android:fillColor="#81D672"/>
<path
android:pathData="M877.7,398.4l-353.2,-205.3 -26.6,-16.7 353.2,205.3 26.5,16.7z"
android:fillColor="#792D2D"/>
<path
android:pathData="M512,831.5L158.8,626.3l-0.7,-253.7 353.2,205.3 0.7,253.7z"
android:fillColor="#E9E8E6"/>
<path
android:pathData="M851.2,381.6L497.9,176.4l-170.5,-107.3 353.2,205.3 170.5,107.3z"
android:fillColor="#792D2D"/>
<path
android:pathData="M680.6,274.3l170.5,107.3 0.7,253.7L512,831.5l-0.7,-253.7 169.4,-303.6z"
android:fillColor="#D6D4D2"/>
<path
android:pathData="M511.3,577.9l-353.2,-205.3L327.4,69l353.2,205.3 -169.4,303.6z"
android:fillColor="#ABABA9"/>
<path
android:pathData="M472,618.5L118.7,413.2l208.6,-373.9 353.2,205.3 -208.6,373.9z"
android:fillColor="#F25A5A"/>
<path
android:pathData="M472,618.5L191.1,455.3l208.6,-373.8 280.9,163.3 -208.6,373.8z"
android:fillColor="#DD4A4A"/>
<path
android:pathData="M472,618.5l-208.6,-121.2 208.6,-373.9 208.6,121.2 -208.6,373.9z"
android:fillColor="#FC7E7E"/>
<path
android:pathData="M472,618.5l-136.3,-79.2 208.6,-373.9 136.3,79.2 -208.6,373.9z"
android:fillColor="#F25A5A"/>
<path
android:pathData="M680.6,244.6l210,132.2 -12.9,21.5 -26.5,-16.7 -170.5,-107.3 -169.4,303.6 -26.4,47.3 -12.9,-6.6 208.6,-373.9z"
android:fillColor="#CC4848"/>
<path
android:pathData="M465.1,241.1l-0.4,66.2 -87.7,157.6 0.4,-172.8 87.7,-51z"
android:fillColor="#D6D4D2"/>
<path
android:pathData="M377.3,292.1l-0.4,172.8 -88.3,-51 0.4,-172.8 88.3,51z"
android:fillColor="#E9E8E6"/>
<path
android:pathData="M465.1,241.1l-87.7,51 -88.3,-51 87.7,-51 88.3,51z"
android:fillColor="#DCDCDC"/>
<path
android:pathData="M477.5,241.6l-0.1,40.1 -99.8,58 0.1,-40.1 99.8,-58z"
android:fillColor="#C4C2C0"/>
<path
android:pathData="M377.7,299.6l-0.1,40.1 -100.5,-58 0.1,-40.1 100.5,58z"
android:fillColor="#D6D4D2"/>
<path
android:pathData="M477.5,241.6l-99.8,58 -100.5,-58 99.8,-58 100.4,58z"
android:fillColor="#E9E8E6"/>
<path
android:pathData="M312.5,241.6l64.7,37.4v-75l-64.7,37.6z"
android:fillColor="#21201F"/>
<path
android:pathData="M442.3,241.6l-65.1,-37.6v75l0.4,0.3 64.7,-37.6z"
android:fillColor="#434240"/>
<path
android:pathData="M562.2,381.1c-7.5,2.4 -14.1,6.5 -19.6,12 -5.4,5.4 -9.5,12 -12,19.5 -0.7,2.4 -3.9,2.4 -4.8,0a48.9,48.9 0,0 0,-31.4 -31.4c-2.5,-0.8 -2.5,-4.1 0,-4.9 7.5,-2.4 14.1,-6.6 19.5,-12s9.6,-12 12,-19.4c0.8,-2.4 4.1,-2.4 4.8,0 2.5,7.5 6.6,14.1 12,19.5 5.5,5.4 12.1,9.6 19.6,12a2.6,2.6 0,0 1,0 4.9v0z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M193.4,620.4l0.4,-122.2 12.8,7.4 -0.3,108.2 -12.8,6.7z"
android:fillColor="#D6D4D2"/>
<path
android:pathData="M206.2,613.8l93.6,54.1 -0,14 -106.4,-61.4 12.8,-6.7z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M206.2,613.8l40.9,23.6 12.2,7.1 40.5,23.4 0.3,-108.2 -40.8,-23.6 -12.2,-7.1 -40.5,-23.4 -0.3,108.2z"
android:fillColor="#0074D1"/>
<path
android:pathData="M247,529v108.3l12.2,7.1v-108.3l-12.2,-7.1z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M342.1,706.3l0.3,-122.2 12.8,7.4 -0.3,108.2 -12.8,6.7z"
android:fillColor="#D6D4D2"/>
<path
android:pathData="M354.9,699.6l93.6,54 -0,14.1 -106.4,-61.4 12.8,-6.7z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M354.9,699.6l40.8,23.6 12.2,7.1 40.5,23.4 0.3,-108.2 -40.8,-23.6 -12.2,-7.1 -40.5,-23.4 -0.3,108.2z"
android:fillColor="#0074D1"/>
<path
android:pathData="M395.8,614.9V723.2l12.2,7.1V621.9l-12.2,-7.1z"
android:fillColor="#FFFFFF"/>
<path
android:pathData="M761.1,442.7l-19,11 0.4,222.6 19.1,11 -0.4,-244.6z"
android:fillColor="#E9E8E6"/>
<path
android:pathData="M742.5,676.4l-103.5,59.8 0.1,22L761.6,687.4v-0.1l-19.1,-11z"
android:fillColor="#81D672"/>
<path
android:pathData="M742.1,453.7l-103.6,59.8 0.4,222.7 103.5,-59.8 -0.4,-222.7z"
android:fillColor="#3F9AE0"/>
<path
android:pathData="M742.5,568v22.1l-103.5,59.7 -0.1,-22 103.5,-59.9z"
android:fillColor="#0074D1"/>
</vector>

Some files were not shown because too many files have changed in this diff Show More