1.README,以及对应的图片

Signed-off-by: 15952050689 <lifz0125@thundersoft.com>
This commit is contained in:
15952050689 2021-11-10 15:33:36 +08:00
parent 48703bf674
commit 3970869219
33 changed files with 395 additions and 156 deletions

519
README.md
View File

@ -1,68 +1,52 @@
# Settings 源码开发说明
大纲:
1. 项目介绍
2. 工程结构
1. 目录结构
2. 整体架构
3. 代码使用
1. 代码下载
1. 从码云clone代码配置ssh下载代码
2. 环境搭建
1. 下载DevEco Studio
2. 安装开发SDK
3. 更新 ace-loader
3. 工程导入DevEco Studio
1. 如何build项目
4. 基础开发说明
1. NAPI 接口调用
2. 异步回调的使用
3. 如何引用资源文件
5. 典型接口的使用
6. 签名打包
1. 签名
1. 签名文件的获取
2. 签名文件的配置
2. 打包
1. debug打包
2. release打包
7. 安装、运行、调试
1. 应用安装、运行
1. 重新安装需要清理缓存的内容
2. 应用调试
1. log打印
2. log获取及过滤
8. 发布hap包
1. 发布到码云
## 1. 项目介绍
Settings是基于Harmony OS平台开发的基于OHOS提供基础设置功能。主要包括页面展示跳转逻辑、基础设置项(wlan设置、亮度设置、应用管理、日期和时间、关于手机)以及本设备其他应用设置项的收集、其他设备设置项收集的实现。项目采用MVVM架构模式让各个层级之间不直接访问减少相互依赖。
Settings采用纯 JS 语言开发,开发过程中不涉及任何 Java 部分的代码。
## 1. 项目介绍
Settings是基于 OpenHarmony 平台开发的基于OHOS提供基础设置功能。主要包括页面展示跳转逻辑、基础设置项(wifi设置、亮度设置、应用管理、日期和时间、关于手机)以及本设备其他应用设置项的收集、其他设备设置项收集的实现。项目采用MVVM架构模式让各个层级之间不直接访问减少相互依赖。
Settings采用纯 ETS 语言开发,开发过程中不涉及任何 Java 部分的代码。
## 2. 工程结构
### 目录结构
```
/applications/standard/settings
├── entry/src/main
│ └── js/default
│ ├── common # 公共代码存在目录
│ ├── pages # 界面源代码文件存放目录
│ ├── models # 数据模型源代码存放目录
│ ├── component # UI组件源代码存放目录
│ ├── i18n # 全球化资源文件存放目录
│ └── app.js
│ └── resources # 资源存放目录
│ └── config.json # 应用信息及组件信息清单
```
├── entry # 主entry模块目录
│ └── src
│ ├── main
│ ├── ets # ets模块目录
│ ├── default
│ ├── common # 公共工具存放目录
│ ├── model # 数据管理和决策逻辑存放目录
│ ├── pages # 组件页面存放目录
│ ├── res # 部分图片资源
│ ├── resources # 其它共用资源
│ ├── app.ets # 全局ets逻辑和应用生命周期管理文件
│ ├── resources # 资源配置文件存放目录
│ ├── base # 默认语言场景,图片资源,字体大小,颜色资源内容存放目录
│ ├── en_AS.element # 英文语言场景资源内容存放目录
│ ├── rawfile # 本地配置文件存放目录
│ ├── zh_CN.element # 中文语言场景资源内容存放目录
│ └── config.json # 全局配置文件
├── signature # 证书文件目录
├── LICENSE # 许可文件
### 整体架构
![settings_en](./img/settings_en.png)
![](./figures/en-us_image_0000001153225717.png)
设置 整体是 openHarmony 系统中预置的系统应用为用户提供设置系统属性的交互界面。例如设置wifi状态系统时间屏幕亮度等系统属性。
Settings整体采用MVVM架构设计。关于MVVM架构中各层级的描述如下
View视图层负责界面数据的展示与用户进行交互。
ViewModel视图模型用UI Component将公用逻辑抽离建立一套公用的ui引擎处理视图层View发送的业务逻辑处理请求并连通 Model 层获取数据。
Model模型层负责处理数据包括wifi的model应用管理model日期时间model等。
## 3. 代码使用
### 代码下载
基于L2的 Settings代码可以采用从码云上克隆的方式下载。
[下载地址](https://gitee.com/OHOS_STD/applications_standard_settings)
[下载地址](https://gitee.com/openharmony/applications_settings)
#### 从码云克隆代码
##### 1.配置SSH公钥
@ -74,18 +58,21 @@ Settings采用纯 JS 语言开发,开发过程中不涉及任何 Java 部分
ssh-keygen -t rsa -C "xxxx@xxxx.com"
```
> 执行完成后,会在用户目录下的.ssh文件夹内生成 `id_rsa``id_rsa.pub` 两个文件,其中的 `id_rsa.pub` 即为生成的 SSH公钥
2. 复制公钥内容
输入`cat .ssh/id_rsa.pub`,复制打印内容。
![](./img/3-1.png)
3. 在设置->安全设置->SSH公钥 中设置 SSH公钥
将第二步中复制的内容按照画面提示粘贴到码云上相应的内容区域,并点击确定。
![](./img/3-2.png)
>
> ![](./figures/git_ssh_pub_key.png)
>
> 2. 复制公钥内容
> 输入`cat .ssh/id_rsa.pub`,复制打印内容。
> ![](./figures/3-1.png)
> 3. 在设置->安全设置->SSH公钥 中设置 SSH公钥
> 将第二步中复制的内容按照画面提示粘贴到码云上相应的内容区域,并点击确定。
> ![](./figures/3-2.png)
> 注意在码云中添加SSH公钥之后需要进行账号的密码验证验证通过才能成功添加。
##### 2.下载代码
1. 浏览器打开[下载地址](https://gitee.com/OHOS_STD/applications_standard_settings)。
1. 浏览器打开[下载地址](https://gitee.com/openharmony/applications_settings)。
2. 点击“克隆/下载”按钮,选择 SSH点击“复制”按钮。
![](./img/source_download_1.png)
3. 在本地新建 Launcher 目录,在 Settings 目录中执行如下命令
![](./figures/source_download_1.png)
3. 在本地新建 Settings 目录,在 Settings 目录中执行如下命令
```
git clone 步骤2中复制的地址
```
@ -98,139 +85,363 @@ Settings使用 DevEco Studio 进行开发,开发前需要下载 DevEco Studio
在下载页面下载 DevEco Studio 的安装包压缩文件([下载地址](https://developer.harmonyos.com/cn/develop/deveco-studio#download))。
下载页面如下:
![](./img/ds_download.png)
![](./figures/ds_download.png)
> 注:下载 DevEco Studio 需要注册华为账号。
> ![](img/hw_register.png)
> ![](figures/hw_register.png)
**2安装**
将下载下来的压缩包解压,得到安装文件如图:
![](./img/ds_exe.png)
![](./figures/ds_exe.png)
双击安装文件进行安装,安装过程如图所示:
![](./img/ds_install_1.png)
![](./figures/ds_install_1.png)
![](./img/ds_install_2.png)
![](./figures/ds_install_2.png)
#### 2. 安装开发 SDK
DevEco Studio 在安装完成之后会自动下载开发 SDK 下载过程如下图所示:
![](./img/sdk_downloading.png)
#### 3. 更新 ace-loader
> 由于最新的 ace 框架尚未发布到公开版 sdk 中,所以为了让应用能够顺利编译,需要替换 sdk 中的 ace-loader。
替换下面两个路径下的 ace-loader 文件夹。
```
Sdk\js\2.1.1.20\build-tools
Sdk\js\2.0.1.95\build-tools
```
// TODO 这里是否需要npm install
![](./figures/sdk_downloading.png)
### 工程导入 DevEco Studio
> 由于 Settings 的开源代码中删除了工程中的 `build.gradle` 文件,所以我们需要在相应的目录创建 `build.gradle` 文件以保证工程可以被正确导入 DevEco Studio 。
#### 1. 为 Settings工程添加 `build.gradle`
1. 在工程根目录下,添加 build.gradle 文件,内容如下:
```
apply plugin: 'com.huawei.ohos.app'
ohos {
compileSdkVersion 7
defaultConfig {
compatibleSdkVersion 6
}
supportSystem "standard"
}
buildscript {
repositories {
maven {
url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/'
}
maven {
url 'https://mirrors.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
jcenter()
}
dependencies {
classpath 'com.huawei.ohos:hap:3.0.3.2'
}
}
allprojects {
repositories {
maven {
url 'http://repo.ark.tools.huawei.com/artifactory/maven-public/'
}
maven {
url 'https://mirrors.huaweicloud.com/repository/maven/'
}
maven {
url 'https://developer.huawei.com/repo/'
}
jcenter()
}
}
```
2. 在工程的 entry 目录下,添加 build.gradle 文件,内容如下:
```
apply plugin: 'com.huawei.ohos.hap'
ohos {
compileSdkVersion 7
defaultConfig {
compatibleSdkVersion 6
}
arkEnabled false
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.har'])
testCompile 'junit:junit:4.12'
}
```
#### 2. build Settings 工程
在添加完上面三个 build.gradle 文件后DevEco Studio 可以正常导入工程。
选择Build → Build Haps(s)/APP(s) → Build Hap(s)
![](./figures/ds_build_haps.png)
## 4. 基础开发说明
### 多语言支持
#### 定义资源文件
- 在 `src/main/ets/resources/`目录下,根据不同的语言定义不同的文件夹下面的 `string.json` 资源文件。
![](./figures/ds_i18n_files.png)
#### 引用资源
- 在对应ets文件中可直接通过`$r()`引用。
````
this.title = $r('app.string.world');
this.icon = $r('app.media.icon');
````
## 5. 典型接口的使用
1. 读取json配置文件
```
import fileio from '@ohos.fileio';
readLocalFile(fileName): any[]{
try {
let stream = FileIo.createStreamSync(fileName, 'r');
LogUtil.info('settings readLocalFile stream:' + stream);
let buf = new ArrayBuffer(4096);
let len = stream.readSync(buf);
LogUtil.info('settings readLocalFile len:' + len);
let arr = new Uint8Array(buf);
let charAt = ' '.charCodeAt(0);
for (let i = len;i < 4096; i++) {
arr[i] = charAt;
}
let content = String.fromCharCode.apply(null, arr);
stream.closeSync();
LogUtil.info('settings readLocalFile content:' + JSON.stringify(content));
return JSON.parse(content);
} catch (jsonError) {
LogUtil.info('settings readLocalFile jsonError:' + jsonError);
}
}
```
2. 查询所有应用信息
```
import Bundle from '@ohos.bundle';
Bundle.getAllBundleInfo(0)
.then((data) => {
console.info('Settings getAllBundleInfo '+JSON.stringify(data));
}
);
```
3. 获取wifi扫描信息
```
import wifi_native_js from '@ohos.wifi_native_js';
getScanInfos() {
wifi_native_js.getScanInfos(result => {
this.animator_on = false;
var clen = Object.keys(result).length;
console.log("[wifi_js_test] wifi received scan info call back: " + clen);
for (var j = 0; j < clen; j++) {
console.log("result[0].ssid :" + result[j].ssid);
console.info("securityType: " + result[j].securityType);
console.info("rssi: " + result[j].rssi);
console.info("band: " + result[j].band);
}
});
}
```
4. Preferences 存取数据
```
import storage from '@ohos.data.storage';
// 数据存放路径
const PREFERENCES_PATH = '/data/accounts/account_0/appdata/com.ohos.settings/sharedPreference/SettingsPreference';
let mPreferences = Storage.getStorageSync(PREFERENCES_PATH);
save(key,value) {
mPreferences.putSync(key, value);
mPreferences.flushSync();
}
get(key,defaultValue): any {
return mPreferences.getSync(key, defaultValue);
}
```
## 6. 签名打包
### **1签名 **
### 签名
> 打开项目工程选择File → Project Structure
>
> ![](./img/6-1.png)
>
> 选择Modules → Signing Configs
> 将对应的签名文件配置如下完成后点击Apply再点击OK
>
> ![](./img/6-2.png)
>
> 注:签名文件请参考 [华为开发者官网](https://developer.huawei.com/consumer/cn/)
>
> 配置完成后对应的build.gradle文件中会出现如下内容
>
> ![](./img/6-3.png)
>
>
#### 签名文件的获取
1. 拷贝 OpenHarmony 标准版的 prebuilts\signcenter 目录到操作目录
2. 拷贝Settings工程的 signature\settings.p7b 到该目录下
#### 签名文件的配置
打开项目工程,选择 File → Project Structure
![](./figures/signature_1.png)
选择 Modules → Signing Configs将对应的签名文件配置如下完成后点击Apply再点击OK。
![](./figures/signature_2.png)
配置完成后对应的build.gradle文件中会出现如下内容
![](./figures/signature_3.png)
### 打包
> 编译hap包
>
> 签名准备完成后选择Build → Build Haps(s)/APP(s) → Build Hap(s)
>
> ![](./img/6-4.png)
>
> 编译完成后hap包会生成在entry\build\outputs\hap\debug\phone\路径下如果没有配置签名则只会生成未签名的hap包
>
> ![](./img/6-5.png)
DevEco Studio 支持 debug 与 release 两种打包类型。可以在 OhosBuild Variants 窗口中进行切换。
![](./figures/ds_ohosbuild_variants.png)
#### debug打包
1. 代码准备完成后,在 OhosBuild Variants 窗口的 Selected Variant 中选择 debug。
![](./figures/ds_ohosbuild_variants_debug.png)
2. 选择Build → Build Haps(s)/APP(s) → Build Hap(s)
![](./figures/ds_build_haps.png)
3. 编译完成后hap包会生成在工程目录下的 `\build\outputs\hap\debug\phone\`路径下如果没有配置签名则只会生成未签名的hap包
![](./figures/ds_ohosbuild_output_dir.png)
#### release打包
1. 代码准备完成后,在 OhosBuild Variants 窗口的 Selected Variant 中选择 release
![](./figures/ds_ohosbuild_variants_release.png)
2. 选择Build → Build Haps(s)/APP(s) → Build Hap(s)
![](./figures/ds_build_haps.png)
3. 编译完成后hap包会生成在工程目录下的 `\build\outputs\hap\release\phone\`路径下如果没有配置签名则只会生成未签名的hap包
![](./figures/ds_ohosbuild_output_dir.png)
## 7. 安装、运行、调试
### 应用安装、运行
#### 应用安装
## 应用安装
配置 hdc
进入SDK目录中的toolchains文件夹下获取文件路径
![](./figures/screenshot-20210521-105407.png)
> 注意此处的hdc.exe如果版本较老可能不能正常使用需要获取新的hdc.exe文件
并将此路径配置到环境变量中:
![](./figures/screenshot-20210521-111223.png)
重启电脑使环境变量生效
连接开发板打开cmd命令窗口执行hdc list targets弹出窗口如下
![](./figures/cmd1.png)
等待一段时间后,窗口出现如下打印,可回到输入 hdc list targets 的命令窗口继续操作:
![](./figures/cmd2.png)
再次输入hdc list targets出现如下结果说明hdc连接成功
![](./figures/cmd3.png)
获取 root 权限与读写权限:
```
adb root
adb remount
hdc smode当前版本可能仍不稳定执行此命令可能导致后续的hdc target mount 失败,可不执行)
hdc target mount效果与remount类似
```
将签名好的 hap 包放入设备的 `/system/app` 目录下。
将签名好的 hap 包放入设备的 `/system/app` 目录下并修改hap包的权限
```
adb push settings.hap /system/app
hdc file send 本地hap包路径 /system/app/hap包名称
例如hdc file send Settings.hap /system/app/Settings.hap
```
> 注意,如果设备不存在 `/system/app` 目录,则需要手动创建该目录。
> 注意,如果设备不存在 `/system/app` 目录,则需要手动创建该目录并修改权限。
>
> ```
> hdc shell
> cd system
> mkdir app
> chmod 777 app
> ```
> `/system/app` 目录放置系统应用例如LauncherSystemUISettings 等。此目录应用不用安装系统自动拉起。
>
> `/system/app` 目录放置系统应用例如LauncherSystemUISettings 等。
>
> 但hap包需要在该目录下手动设置权限
>
> ```
> chmod 666 hap包名
> ```
>
> 此目录应用不用手动安装,系统自动拉起。
## 应用运行
Settings 属于系统应用,在将签名的 hap 包放入 `/system/app` 目录后,重启系统,应用会自动拉起。
#### 应用运行
Launcher属于系统应用在将签名的 hap 包放入 `/system/app` 目录后,重启系统,应用会自动拉起。
```
adb reboot
hdc shell reboot 不可以直接执行hdc reboot命令是无效的)
```
> 注意,如果设备之前安装过 Launcher 应用,则需要执行如下两条命令清除设备中存储的应用信息才能够在应用重启的时候将我们装入设备的新 hap 包正常拉起。
> 注意,如果设备之前安装过系统应用,则需要执行如下两条命令清除设备中存储的应用信息,才能够在设备重启的时候将最新装入设备的新 hap 包正常拉起。
>
> ```
> adb shell rm -rf /data/accounts/
> adb shell rm -rf /data/bundlemgr/
> hdc shell rm -rf /data/misc_de/0/mdds/0/default/bundle_manager_service
> hdc shell rm -rf /data/accounts
> ```
### 应用调试
## 应用调试
#### log打印
- 在程序中添加 log
```JS
```
console.info("Setting log info");
```
可以在DevEco Studio中查看log
![](./img/ds_hilog_window.png)
#### log获取及过滤
- log获取
将log输出至文件
```
adb shell hilog > 输出文件名称
hdc shell hilog > 输出文件名称
```
例:
在真实环境查看log将全log输出到当前目录的hilog.log文件中
```
adb shell hilog > hilog.log
hdc shell hilog > hilog.log
```
- log过滤
@ -245,36 +456,54 @@ hilog | grep 过滤信息
hilog | grep Label
```
## 8. 发布hap包
### 重命名hap包
将编译生成的 hap 包按照如下规则重命名:
|模块|包名|
|:--|-|
|settings|Settings.hap|
## 8. 贡献代码
### 发布到码云
1. 访问码云的hap包仓库[仓库地址](https://gitee.com/OHOS_STD/applications_standard_hap))。
### Fork 代码仓库
2. 将仓库克隆到本地
点击“克隆/下载”按钮选择SSH标签点击复制使用 `git clone` 命令将复制的地址克隆到本地目录。
![](./img/hap_repo.png)
1. 在码云上打开 Settings 代码仓库([仓库地址](https://gitee.com/openharmony/applications_settings))。
2. 点击仓库右上角的 Forked 按钮
![](./figures/commit_source_fork_button.png)
3. 在弹出的画面中,选择将仓库 fork 到哪里,点击确认。
![](./figures/commit_source_fork_confirm.png)
4. Fork 成功之后,会在自己的账号下看见 fork 的代码仓库。
![](./figures/commit_source_forked_repo1.png)
### 提交代码
1. 访问我们自己在码云账号上 fork 的代码仓库,点击“克隆/下载”按钮,选择 SSH点击“复制”按钮。
![](./figures/commit_source_clone_page.png)
2. 在本地新建 Settings 目录,在 Settings 目录中执行如下命令
```
git clone 复制的地址
git clone 步骤1中复制的地址
```
3. 将签名后的 hap 包放入本地目录,并提交。
```
git add .
git commit -m "提交信息"
```
3. 修改代码。
4. 使用 git push 命令将其推送到 hap 包仓库。
```
git push
```
> 将代码引入工程,以及编译工程等相关内容请参见 **3. 代码使用** 部分的相关内容。
---
4. 提交代码到 fork 仓库。
> 修改后的代码,首先执行 `git add` 命令,然后执行 `git commit -s` 命令与 `git push` 命令,将代码 push 到我们自己的 fork 仓中。
> 关于代码提交的这部分内容涉及 git 的使用,可以参照 [git官网](https://git-scm.com/) 的内容,在此不再赘述。
### 发起 Pull Request (PR)
在将代码提交到 fork 仓之后,我们可以通过发起 Pull RequestPR的方式来为 OpenHarmony 的相关项目贡献代码。
1. 打开 fork 仓库。选择 `Pull Requests``新建 Pull Request`
![](./figures/commit_source_new_pull_request.png)
2. 在 `新建 Pull Request` 画面填入标题与说明,点击 `创建` 按钮。
![](./figures/commit_source_new_pull_request_confirm.png)
3. 创建 Pull Request 完成。 PR 创建完成后,会有专门的代码审查人员对代码进行评审,评审通过之后会合入相应的代码库。
![](./figures/commit_source_new_pr_done.png)
系统应用
**applications\_settings**

View File

@ -18,12 +18,22 @@
```
/applications/standard/settings
├── figures # 架构图目录
├── entry # 主entry模块目录
── src
── src
│ ├── main
│ └── js # js代码目录
│ └── resources # 资源存放目录
│ ├── ets # ets模块目录
│ ├── default
│ ├── common # 公共工具存放目录
│ ├── model # 数据管理和决策逻辑存放目录
│ ├── pages # 组件页面存放目录
│ ├── res # 部分图片资源
│ ├── resources # 其它共用资源
│ ├── app.ets # 全局ets逻辑和应用生命周期管理文件
│ ├── resources # 资源配置文件存放目录
│ ├── base # 默认语言场景,图片资源,字体大小,颜色资源内容存放目录
│ ├── en_AS.element # 英文语言场景资源内容存放目录
│ ├── rawfile # 本地配置文件存放目录
│ ├── zh_CN.element # 中文语言场景资源内容存放目录
│ └── config.json # 全局配置文件
├── signature # 证书文件目录
├── LICENSE # 许可文件

BIN
figures/3-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
figures/3-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
figures/cmd1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
figures/cmd2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
figures/cmd3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

BIN
figures/ds_build_haps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
figures/ds_download.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

BIN
figures/ds_exe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
figures/ds_hilog_window.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
figures/ds_i18n_files.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
figures/ds_install_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
figures/ds_install_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
figures/git_ssh_pub_key.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

BIN
figures/hw_register.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
figures/sdk_catalogue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
figures/sdk_downloading.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
figures/signature_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
figures/signature_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
figures/signature_3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB