From 0f940bf2da2c94231521b3820de25334afabb589 Mon Sep 17 00:00:00 2001
From: MementoMori <1003350679@qq.com>
Date: Wed, 15 Jul 2020 10:53:47 +0800
Subject: [PATCH 1/5] upgrade README.md
---
packageship/README.md | 332 +++++++++++++-----
.../doc/design/pkgimg/pkgship-logo.png | Bin 0 -> 240143 bytes
2 files changed, 247 insertions(+), 85 deletions(-)
create mode 100644 packageship/doc/design/pkgimg/pkgship-logo.png
diff --git a/packageship/README.md b/packageship/README.md
index 336a9466..ffd2e12c 100644
--- a/packageship/README.md
+++ b/packageship/README.md
@@ -1,88 +1,250 @@
-# pkgmnt
+
+
+[English](./README.md) | 简体中文
+
+# pkgship
-#### 介绍
-pkgmnt希望提供软件包依赖,生命周期,补丁查询等功能。
-1.软件包依赖:方便社区人员在新引入、软件包更新和删除的时候能方便的了解软件的影响范围。
-2.生命周期管理:跟踪upstream软件包发布状态,方便维护人员了解当前软件状态,及时升级到合理的版本。
-3.补丁查询:方便社区人员了解openEuler软件包的补丁情况,方便的提取补丁内容(待规划)
-
-
-#### 软件架构
-系统采用flask-restful开发,使用SQLAlchemy ORM查询框架,同时支持mysql和sqlite数据库,通过配置文件的
-形式进行更改
-
-
-#### 安装教程
-
-1. 安装系统的依赖包
-
- pip install -r requirements.txt
-
-2. 执行打包命令,打包命令行工具,其中(pkgship)为命令行的名称,可以随意更改
-
- 2.1 打包生成 .spec打包文件
-
- pyinstaller -F -n pkgship cli.py
-
- 2.2 修改 .spec打包文件,将hiddenimports中加入如下配置
-
- hiddenimports=['pkg_resources.py2_warn']
-
- 2.3 生成二进制命令文件
-
- pyinstaller pkgship.spec
-
- 2.4 二进制命令文件拷贝至可运行目录
-
- cp dist/pkgship /usr/local/bin
-
-3. 系统的部署
-
- 3.1 安装uwsgi服务器
-
- pip install uwsgi
-
- 3.2 修改服务的配置文件
-
- cd /etc/pkgship/
-
- vi package.ini
-
- 备注: 配置文件中可以支撑sqlite数据库和mysql数据库,可根据相应配置进行修改
-
- 如果需要调整 查询和修改相关端口,请同步更改 mange.ini 和selfpkg.ini 中的配置
-
- 切记(manage.py为拥有写入权限,selfpkg为拥有查询权限)
-
- 3.3 启动系统服务
-
- 单独启动manage服务: pkgshipd start manage
-
- 单独启动selfpkg服务: pkgshipd start selfpkg
-
- 同时启动manage和selfpkg服务: pkgshipd start
-
- 3.4 停止系统服务
- 停止manage服务: pkgshipd stop manage
-
- 停止selfpkg服务: pkgshipd stop selfpkg
-
- 同时停止manage和selfpkg服务: pkgshipd stop
-
-
-
-
-#### 使用说明
-
-1. 命令行使用
-
- pkgship --help
-
-2. restful接口使用
-
- 参考接口设计文档中的接口定义,进行相关接口调用
-
-#### 参与贡献
+## 介绍
+pkgship是一款管理OS软件包依赖关系,提供依赖和被依赖关系的完整图谱查询工具,pkgship提供软件包依赖,生命周期,补丁查询等功能。
+1. 软件包依赖:方便社区人员在新引入、软件包更新和删除的时候能方便的了解软件的影响范围。
+2. 生命周期管理:跟踪upstream软件包发布状态,方便维护人员了解当前软件状态,及时升级到合理的版本。
+3. 补丁查询:方便社区人员了解openEuler软件包的补丁情况,方便的提取补丁内容
+
+
+### 软件架构
+系统采用flask-restful开发,使用SQLAlchemy ORM查询框架,同时支持mysql和sqlite数据库,通过配置文件的形式进行更改
+
+
+一、安装pkgship
+---
+支持操作系统:openEuler 1.0及以上版本
+#### 1.环境准备
+
+#### 1.1 Dnf工具
+
+#### 1.2 Python环境
+
+##### 安装 DNF
+1. 为了安装 DNF ,您必须先安装并启用 epel-release 依赖。
+在系统中执行以下命令:
+```
+yum install epel-release
+或
+yum install epel-release -y
+```
+2. 使用 epel-release 依赖中的 YUM 命令来安装 DNF 包
+在系统中执行以下命令:
+```
+yum install dnf
+```
+##### 安装 python环境
+```
+dnf install python3-devel
+dnf install python3
+```
+安装python依赖包(批量安装)
+```
+dnf install python3-pip
+```
+
+
+#### 2.安装pkgship
+
+```
+dnf install pkgship(版本号)
+```
+---
+
+### 安装在容器中(适用于开发者)
+
+#### 1. docker使用
+
+#### 1.1 下载源的更改
+更改repo的源配置
+
+```
+ >[everything]
+ name=everything
+ baseurl=https://repo.openeuler.org/openEuler-20.03-LTS/everything/aarch64/
+ enabled=1
+ gpgcheck=0
+ priority=1
+
+ >[source]
+ name=source
+ baseurl=https://repo.openeuler.org/openEuler-20.03-LTS/source/
+ enabled=1
+ gpgcheck=0
+ priority=2
+```
+
+#### 1.2 docker镜像的加载使用
+
+搜索openeuler相关的docker镜像
+```
+docker search openeuler
+```
+
+
+获取docker镜像,以kunpengcompute/openeuler镜像为主(官方维护)
+```
+docker pull kunpengcompute/openeuler
+```
+
+以命令的模式进行docker
+```
+docker run -itd kunpengcompute/openeuler /bin/bash
+```
+
+启动已经停止的docker容器
+```
+docker start 容器id
+docker attach 容器id
+```
+
+#### 2. 系统的安装部署
+
+#### 2.1 软件的安装
+
+```
+rpm -ivh rpm包
+```
+或者
+```
+dnf install pkgship-(版本号)
+```
+
+#### 2.2 系统的配置
+
+创建初始化数据库的yaml配置文件
+```
+- dbname: openEuler-20.03-LTS
+ src_db_file:
+- /etc/pkgship/src.sqlite
+ bin_db_file:
+- /etc/pkgship/bin.sqlite
+ status: enable
+ priority: 1
+```
+
+更改系统的默认配置文件(根据实际情况进行配置更改)
+
+```
+vim /etc/pkgship/package.ini
+```
+
+#### 2.3 服务启动
+
+```
+pkgshipd start
+```
+
+##### 2.4 服务的停止
+```
+pkgshipd stop
+```
+
+#### 2.5. 数据库初始化
+```
+pkgship init
+```
+
+二、使用说明
+---
+### 1. 单包查询
+
+1. 查询源码包(sourceName)在所有数据库中的信息
+```
+pkgship sourceName
+```
+2. 查询当前包(sourceName)在指定数据库(dbName)中的信息
+```
+pkgship sourceName -db dbName
+```
+### 2. 查询所有包
+1. 查询所有数据库下包含的所有包的信息
+```
+pkgship list
+```
+2. 查询指定数据(dbName)下的所有包的信息
+```
+pkgship list -db dbName
+```
+### 3. 安装依赖查询
+1. 查询二进制包(binaryName)的安装依赖,按照优先级轮询默认数据库
+```
+pkgship installdep binaryName
+```
+2. 在指定数据库(dbName)下查询二进制包(binaryName)的所有安装依赖
+按照先后顺序指定数据库查询的优先级
+```
+pkgship installdep binaryName -dbs dbName1 dbName2...
+```
+### 4. 编译依赖查询
+1. 查询源码包(sourceName)的所有编译依赖,按照优先级轮询默认数据库
+```
+pkgship builddep sourceName
+```
+2. 在指定数据库(dbName)下查询源码包(sourceName)的所有安装依赖
+按照先后顺序指定数据库查询的优先级
+```
+pkgship builddep sourceName -dbs dbName1 dbName2...
+```
+### 5. 自编译自安装依赖查询
+1. 查询二进制包(binaryName)的安装依赖,按照优先级轮询默认数据库
+```
+pkgship selfbuild binaryName
+```
+2. 查询源码包(sourceName )的编译依赖
+```
+pkgship selfbuild sourceName -t source
+```
+3. 其他参数
+-dbs 指定数据库优先级.
+```
+示例: pkgship selfbuild binaryName -dbs dbName1 dbName2
+```
+-s 是否查询自编译依赖
+默认为0不查询自编译依赖,可以指定0或1(表示查询自编译)
+```
+查询自编译示例:pkgship selfbuild sourceName -t source -s 1
+```
+-w 是否查询对应包的子包.默认为0,不查询对应子包,可以指定 0或1(表示查询对应子包)
+```
+查询子包示例: pkgship selfbuild binaryName -w 1
+```
+### 6. 被依赖查询
+1. 查询源码包(sourceName)在某数据库(dbName)中被哪些包所依赖
+查询结果默认不包含对应二进制包的子包
+```
+pkgship bedepend sourceName -db dbName
+```
+2. 使查询结果包含二进制包的子包 加入参数 -w
+```
+pkgship bedepend sourceName -db dbName -w 1
+```
+### 7. 修改包信息记录
+1. 变更数据库中(dbName)源码包(sourceName)的maintainer 为Newmaintainer
+```
+pkgship updatepkg sourceName db dbName -m Newmaintainer
+```
+2. 变更数据库中(dbName)源码包(sourceName)的maintainlevel为Newmaintainlevel
+```
+pkgship updatepkg sourceName db dbName -l Newmaintainlevel
+```
+3. 同时变更数据库中(dbName)源码包(sourceName)的maintainer 为Newmaintainer和变更maintainlevel为Newmaintainlevel
+```
+pkgship updatepkg sourceName db dbName -m Newmaintainer -l Newmaintainlevel
+```
+### 8. 删除数据库
+删除指定数据库(dbName)
+```
+pkgship rm db dbName
+```
+
+三、参与贡献
+---
+我们非常欢迎新贡献者加入到项目中来,也非常高兴能为新加入贡献者提供指导和帮助。在您贡献代码前,需要先签署[CLA](https://openeuler.org/en/cla.html)。
1. Fork 本仓库
2. 新建 Feat_xxx 分支
@@ -90,6 +252,6 @@ pkgmnt希望提供软件包依赖,生命周期,补丁查询等功能。
4. 新建 Pull Request
-#### 会议记录
+### 会议记录
1. 2020.5.18:https://etherpad.openeuler.org/p/aHIX4005bTY1OHtOd_Zc
diff --git a/packageship/doc/design/pkgimg/pkgship-logo.png b/packageship/doc/design/pkgimg/pkgship-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..53905d2ef94063ef52a8a0069448ba5a42fa2720
GIT binary patch
literal 240143
zcmWiebyyRQ^T$DisgyeD5>P_AVGIT$APAd^fV6&TX&5n5L_lc-L>eSUPw7q>-6f-Y
z8;snD5&k~EKkm8b?$7()}{R_4OrGoBj^_9SRBxdY$LbUQvfodcD?uN>Mq&iTkg(X|JxYPC@ZIp7!!R^?&tk_va>F6cqR2{~we~c07I*6#oi!
zo~gg_v)sKpKMpZ@&2l!IBY6)fB?Zy@^XFM$_kOVz++DL*os)^_)%d+Pci%j)HF$aN
z)q|UwFO5QdC~fbBY2Nkz`#}93n>#jWzj6;>im%+PM%8+IcVBJsAFEoOwpfu|^UO4x
zO1>DQ=Z30)kDN?uzi&F`ew#C`1iNsI_x82d
zJfSq8dBV3eXmP14GCJpOg3h&$oy*VoQwoKB!+A64s=@qlRMIx?=Q&Y1y3$95wCl68
zG+A*PFdCD&(PZgeX?Pv`q}_thXhKjI0o~UU_q?g4-Lrn4Q`#V}Vo>v9i))Wbj4+GR
zN3LKN?W0t$7+e(Le)#!PBwcYpKHR$&Z$4T1?bN4V&5q#Q@
z^Ci4!nfOjg?#YLbUA^+7u8&HU^tYH7sn|dG*}<7&5Mtz%%!PaA1o|hTzrVt
z1m%};1E|sc2BX6*4TeFijj>$tSdOuvrc)qW%_}pU%&{-#WmU2>5p_Mugfs}0K~9K!
zeQoj07FZrrry6kqXK0O=f{!LPYYdvTgR2DS-H1k4uWLR7TGLYD^JI}Mc+Pj{0fB#u
zDykKaXLaS(B7L(Fz7^VX!DXZUIz=%`(yK7HGheF*#J6p^^=v#gynwmSeo2Oxxb2W8
z+qb>qP3|{lU+mA;#4ez1$6ZVd4Z!{`!astuers2LNBNza8d4y=-+D-|A!3@-k9)Kr&5gwmfYAYB#8<1vTw>5T%^B
zzLc|t!2@%$dwiQ##Q%CsW~&_+OYaPl*e_<PjO
z{HP@KC)i+p^`yb9%KSS|AZb?GGfxFR*jB9Cq!~9R
z!j`YS!vZ>TW9eu&YT_>T`5xys{daOX_o5LW?&fF3Y^AQMx}r5#IEzDdag4s<$QGNU
zb%hv98=9GYFXT>$+@EHzo*f=%54-I)ebzMK^LvST$&}|gL^8wV-V=1p8l3=@CkP?%
zRDyz;++}>S+Z@~!>m5h^LtS$0tcM5+E0F(^0ZTb36t!ixla*QN9;DE*SfzWmS>3?u
z+(Gf$^;_KWBNdMO*`vv!5a^%dc^M{EGp#!sJzIh4Q--GlgaDOy&68y=bX0M-I0+G{
z>Kt=M4jKjcp63qvuUhaX<^G+efy8vX01^~PHP!(`FxVAhAQ(SUHq^EM^
z%=$JOaj*-E9lGFS(7wnKp34@tzA9Opj5t`zv3@=jp&36;a&|7Pr|~bT`Y;(gUn^{M
z=~xrf&Q(xrvE1X=^kLn;m?d^zPF!?A%&YcPD`h+hq!_n$TAJ3fIFjAgB
zv##G>)aE&S8@8KffKF2pi(37_h;?W@BPidAG=@Dfyz($odQfPf<(o2T<<>xKm`%I1
z4#dVA*4Zzs1ie7pv%xecS*K~V%<0$;tu15u<=1V|EUGqa{8uaV$*}g32BjWfE}mnj
z3C;(O>l5h{$F=kNEZXhvl}d`Oe@{M{*%m_lTRgqC!rO4a-*d941ol7IPCS1!%javu
z(P$_7vv7E0IP;-39mTJ@{;dJYeK}7aFP50dE?Nk@Z=15W+);+RUt3)Iq+wxQ#vbXW
z9={n>sX4P}MHXR=EWx~O8g6p0hWE~;1uuA;wz&PhdwSlDMK;g0B3{2AE&D^;`EYm2Q8G%;iOi;*#Z#kv;)QKvCJ|kZPwg{Ns8o$^0BqX)E
z*RwytTm0fqQ(l_vxxeLuk;(l`saY2ZZpXoxf1VAl)8w~#HK3TvGT*`5mDlfuIs}sd
zz}B2P(MjWjoDx-?f1UI~`O5E8SyX~1oPtw0{@M7SEIzizF)o#7VBQB7!3gm-^4!Dg
zCef3#BJp8vB#nAswQJj>P@Q!bz1ho(8W2WP{17YdeZa1SX06*UMZz|`;43<1jF2M)
z#RHJdz}s(iG`5^V(L;C}G3K8fY7psgfb~My?F)Q=NBL!jTm+fYB%FK^OmHE?(LYpw
z`v{33#K#Kxt5_BI%RF87+KT0!6kbBbccR=ea-iP9Ko0F*#fp0=BLeY-FOn&hQ6N}uvL1MXTy(_$B+8_$k3|r
zt~GXNRlJv(nIX5Ow)>sUmzroG=}8ykEP_o<^b%_~ab$>-WEdg%GOJiu*i5;F8qAk1
z(O(%`H)f%}@j^!kA7}wzyuOnYB@RC740b5=$=qwMzU}zSFj#&^N|#2ugrlDQ{j2Y8
zyqS|JufJ1Qa%L&Rlq`NpPCpaMXA+}QUzDGT8ljWbnqDle=OAK@5ga!kN79?9s#!DN
zkd6WN~PY{0q8sd!6kuow44uR|qar*0pimJRa5nYr|6&&U6c
z+$L6^zw17NtHNebEZ5U!=rhvBM&dXX(i(gd{9t64~4Gq17S(w|N8EJEoD12R=)#2t*ujAkLmii21HE
zJhOMNNs4LC6x%5mbRWvMG}dKU$%_VAKLZ=Ytt}R%4NvJO54nVRSVu(q!qzz61VB@!z83G(~!{N}VA4TzW4T+BKZ!&NMJMshvnKP5BC9C#QO
zZ3L+iRn3Ko(Yg^%vkjEvrvwF6EaU{HO6p{uX`h%x<5U>m^7EW8(xj1A`3l6+lAKfn
z1<4zOrV}G>h1K#M!)-CWyYJC&`(KTDvg8&L9M>JQgkCPe)?Y-Z(u4Y?yz=MOePgP1
zWhyUf>hXCjfqs;>iQSy|$QN>TtnEaFzz;!xFVfc+1L{Zx7dp%FqVSBv$04qqbUf!z
zz5mo&En}@1lQ13-BgPPx%(53R_!n*pjV{##rQR~C%kcU8iuKY7m9Ya9##I}|sO->2@}OcCHgYNvb6;5p%oGI
zU~cAZm9r8rc3Dk#3qN4{`m=3eS~BZDni~52*uwkllAHx>E(&Ey;BzpW==9m#qxgPK
z6Rn63G0b3Ft@%FIPldphJ$ZT25{8`6;AKrCP+Eo9F&o>|lkEz0@lC?;!%`lS;S1fvBP1#XU}ef#e&+sKT#U2TYIpWPH~68q)+oz1o}DN2=i*CQ
zU6=th0%ztQu?&?BBv@p+g4H&Ppi+a~K|xCI|ng5P++
zd+hIEzxV?osX+IElSvYuf*j_OAUj}{9X;!JF^?**dRX=o-8i!p+psH(f`&caI+Q`-
zfOAStUhe*AQFv$H?I|s
zh^ug&tDb%>DBf7$k9A>A-4~JOk(U*1)(=XTq24Jww9t{P)*uIX&W!&(Q_QM2&N_I?vJf!yH7u5Xc~!rC
zxZd4D!iy+j1-jev2PaA@s5Q%|$8YAvSxDiWib`oin{$I5h`#sgrl}eZR7-3+1In@yj
zHdYU>?W2g_#PsL_IA^7>N!;5)Tyf+{7MmZx6Fi`)oj51aLZWl!+Nn?43LsSvE0xUl
z5#12Hdl)QWHCZ9)WeCbU!P!^+WD9!qIqBppsz#S&_TL1cUDFJkUnn7wG^Lf7j
zYTIL+8XX}`er}d;aLB}$FAZ0pG$T7;I^#E>WA`)8mc4Jt
z8G$Q()PVXL_U1u)i!Wg$`uB)Y$)V+OqB(uI458XCZdG3Eg0;Ow`_j*UGiEzM^W3Z&H8*#@!bLAT
zaw*t4I-d2@WKwc36tLYveDXGRe*#0mu5b8Jgd`w&tH*wbrdY`yCl|+}OL-7RX&b|9
z{a@2N%L4^4?}d57!Sm43>*9$gmVQnVi#mcGY)Wu?qWldf#UMcC{`7DvCUdD==8L
zd$E=L*lOMm8tW`FqE=hdq1ADhHv>@sb^n<$#dJefec=&JyX^d9ZBn9JLE777d_c!cSx~;DNM?so6@N=6;wdEJCYYpl
z{E+edgv5I}?PRfHHMXC;+w@g@MN{<(Vq9-${v?U#JWhU=uYJdG@#E3TEe(ahiPWRQ
zNpUp=j3DE_A$shqs|L>(z!(^CzLlYr2%^Gh#zm7yYxSFQfLxwKEkiA%f90XySlIY>
z(zVREa8t3)9hQ_EiDKTLst2+z4@|n57#RcDnnbdj2EH-qdzxtUY=&pcg72D$&lDT9;H3iA_3s#9x)#+kYPx{+j#OcS{
z`#a$|B7HKwzN$@BQxJ
zY&SAg2?lp}Tw-yxqJ%rGMJBlfr9?{P35$!j0neAndQgxpeO9Hms!Lee-bjGLT_wZc
zw-0W)5GmN5EYa-*Yh#7M9
zv5ZSx=8<&v#TCfq-0>hIZB=?=_7#f$v81zg6|GmxEq+3Rs$kd&s6>s2g15UjZ
zS@il?4`Td^1dn`f2poa70}NW`JB1yzpSHkt?2w9_nZZgS$a_lndCqnJJ(fvFK#F#p
zjE4)A^7w&dCZmOvs?5@nl(wJ7?>Und`PLHkf3y^g`<7PEya@P|aVZxRDzFp~fJMuV
z8OCF@7#q>41{sQqq0{5I79Y5lLg@IMay@_!n$%6v$LDn4?kNRM4MyB#oq6{?hw{O5
z3kn6QYawNUuR6SO@@!*HEqKm|ZdOJaMGeLd9)yaOs&xERZF|1
zuyj`fF$0KWT`ZNJyw~GSejjV>3(Ep~ZfDw<4ut!m)j9%ta!yuZMfpL39}PC;`}eA|
zRMURS98QlXa%WfPb~8SsSv~l&7uWXYpAZk%=QhuVPGjbvCoi({G`@e<0Dh)f>>>;ffdJ28oPlvT4Wfc>hS&0jy-%RMyCcCAy)pcN{tx
z_cub1Yy7anNxla!dGu?vzL($I63uM8Z`6WWUEX=Y_#pl#ByNO=`{3uG%)VAKYio!^
zl`y+_*p6##JgUDdM0LbxHCVT;5F9=eA3R$+uv)tyw%j*kTwl({6dyNp`s1wnsBo4JNnb_GXi+FrG~Gt7Dh-ZUfh|s
zv`P!!WL?Cc%dLmKXKGw6bn8hH%xW>T^QaO^VrfaHUF17(*AK>2*YP(|tcg5}#Fon*
zw{@+sg<(81Z)w)`DV$?8-L%~})eK%&PY#~wjoDv+6gJjv!A5{5RcRiR%mlf<*I6>ef=JE(!I!8$3WdUAKecNn^);RiYLKzS7VC(?UNSk2Ehkf8D5=veE|vtJ%S@N
z0+_<2&8_{&Z(!qbj`jMRg3XGf>8~cZTL#)c;0NDk8!+vIFxP!xR{hTRU{P&>*=Zwy
z;KQ8b^*_k0hon1L>AP3pckj|~fr2esq_N+iV5%0YAEJB{Y`;>c2XpP{PLr5EIV7t)
zQ9M`zmFTSnPdq!n_+uv6dypM|qnO|7uVYJ!$>o#y_p7(hagICOIDM7xbq)U|o5sVVVGk+6=S#1Q{XT@GR0Q_$
zLmGd^_Z8~}IX0AJ_)Xv&p%gPcR>62(l(&I+97NSIx@v4JdnMxgOZH%g!l5mpkU~mq
zTp$}TZ;k<8*sUzvsVlfSA#64{e&1>n#x*t)v}s>1q^+%zG3h0@*C!Y>qU;hIc$8dd
z)osSv7oV6yW~-LpXN4tMd8Wh}uc&Q=(FfJK{ri@RSiPB>H^UF^PBm8pp9`kZ4ha&h
zZ0UpHiA`U%+n9J-5kjvBPY&QM3>XpdHXC^|s1Z38pG3u)g--))Vb3LYeDO+^vf7Q_eUOap~yUZsk
zn@N}8RJmu7%s6DJ4m+YW)iP0V~$G$6ilnLB;NLhu=^ep5a5@N@pHhTl}=^
z4~HCwc4*WHyG*PfTh0R*kRZH%-x7RK+5%E=<-Pv?3nHNFRK+*WzNhTqI8mXp9S
z8UH=PEn5Wh&h@Nke%Vf%+#b<~`ed%TyPF?V1(jA$M(?d-`*wg?qF_*0f#mO*9$wxA
zNYa~2zqNXHHjj@2szA!h%WL*ts7#WBJJrEKd?*-5nbXIH$>U*TM==MYY3z&W;|EwO
zX(mg`DT0^vedx>&_0XaWYUY+UU*moz^*#8QBu}G&z$7#st;DOwgPyi1GVb9ar+Yb1
z=A0fbvup5g8Y}}J)6%gCR+uY~#qK8ZyO<(SRVak}$f1DS#uPH>aZhepn}t$=vT3<0Rx9-7gpJ42yQjyt5PuH_UL*^
zhEyzf@W6%+74G1h+X8MK@wa9qZ9GNsxs@XX(P7*42}mAKfx8iq{U#E<3QOqpkDm%bf{H~MKfPAS6%VwA2*v|>77XK#
zYXegpsl6wIAI55PK0~lUoH)fALX++3KCakt7G*1b0qgiG{oUSAXY~BJo&~htQ=E(1
zJ)5NF-a>*EwVRF8F>GwFi^Mu_TT)blI_ZNkD6k?X6Hy&kJFR5m7`75&bWk+PIA;{N
zicr1}YmBs*`QR;MKaB%WDVGa!(_e6N2Ir;7QwDZ99oP+dcfdPm
z3{YY7)g9PN87@k$DJe;K43lfPy}MUvLb-`x0V0U_Q-Oq?Nbu3c><8@khR7`
zuOKCB=~T$vZ{Rie!Wb<*X$1xURDDFXmY3y;loVE8H8#Umk?NB@-1`7I-Blov2MA*#
zl)idz$tk1Ane&Gtv)YxSv>Mp9^F<>Z8c1Pp4~6$hk_<*ul=p9*^UZtLh=}c(nuplr
z9R%r%|EjZv)@qG9#y6aN9I?tw&s^HLDF}rvEhhRtK{W+c8Ejs&2;l&9mO$PxND>!k
z()*|Hs%*c}xJ?L%nk!Zpn~ZJFb8ZCuoX&w&1bW*Y4}6O474?yqPm++-OY-VTb*f|(|opJ?#>WnilWPr>5Tcw`C6)YXR^*SqeY?d>lvU86#5n#nWu
zsWFo|t+^*ZK?K+HC&@D>*vC!dbu}JhkY4J8)f-K+TSUWyo=MceVM?k#ue4_NA7e81
zW^$qB(a28E%5x5=mRjLz+;64zuIcWv!K9@z<|4XW!J#B=#kEAI@F`>M1wVxow#^k{
zZ!L3}>APWlQs36?pHk1=t_*)?xz!hvJvLJ>g_X&&(ql?&y$!0Iu`3GD;rXG(mi!4T
zmSm~e_0`CVxk7}1nmuvMn;q$d6
z@E4UW`@iCv5x1m>pT|?ltGDeg8T8K+#g1rTmUxu6w9m@KF~+SEhH2o>KhZ4eyES3F
zN_`N;*-3?`w9R|mHbZ|?0qKagwaKcR(yH4L-O=XES`oH#EV9r?ooPWYH^aB1>c4;0
zKIwRZ@{}dmnpjC2r&OFJN_kV^)10Wfl>-^mhLpYJuR>n6udOD6aWy85Qb;%CQYN~S
z5h6Xvk!B}a%=l+j55nnxCufTCtH^$9-OAH!e&T03$&ImJ_s@kWIOb-rQeeh
zyn)pm`4frO%o?P%bRRwJV+(prul-zsY-G+AlvM{^i|5WmWi!(oq#ied8s`&Hi
z0AujRQwV{g^MwlhqTjT36v*}ur7m7&x{@*uI~dO%K6bG8n**~_QY?ELF!3x+$JMLU
zshm(jYFbH7*ViX#$f?qNS;%Owv&2=dm3K-0kr%zhzv=e(0gJu=4t;)cU)V2KTLdj;
zK>a6a4xLMnux{CQvDurU*qdLFdacAn_n@^W&loN7T?Q;}j(JkavTx5Tb6p4R^GY=D
z*M$Azpg+^Bllq_~UK7A+)WWs*AxGLebllp2e$?EeLy$NVD}R{W|AK=*OwvW?VvUoi
zh&p85UIxhhucfDvCNTg_h*1t?&BU(p=FlZU8WJDduH`Gp_I`POv5_R=r7*^0Bh>2d
z<0(c+Gwt}OH0@I20Ymx~FEffg86E6%xi!T{fJb_K9JN)e>q}KslWBT!@h#-TWL&^c
zV~^u$)Bo*pOy*I#Wn=Z*!Rc#1zeFQd6>~%y%U6|faiECNq&4y!y;v(fK5ff$R
zYk19~vAbHZM5O?e4a>no4Z)VN+Z7*WIlU}eDK5vtfO9iWnZnwF-d)Ppzt)w-)wHd?
zedSeV1g6YqY*_Ou0n!gB?1K}%blOy+>opInE{MG-yn`L
zw)f?>okaQ`eV#bbFkYT00o!)4tX;k@p3DqRuWXaM&tM@=?y05D-vi<5l{RdU
zegiB2@Qt2#BZjq87F;(FYpc{7Jklwb%6*K_wIe#BfFNuo4p{M_eGK=dsRRHK1YJ>5
z$Eo4Ey=!NrxNw8tIEJSz*0nQAb6(7P{EwXemJ(p={bt6K9KT-uJyg!k`}1X5G3rmP
zhJiHt_iZ9itWg69B0`uRH}Ph*kV~cl3fgj}>MRGG!s@%b$NN*{aKaMjAC_B9K*v_f
zN1rY}QgTY>!hkM3D{5fiV+6A{V*7kT9x$RG)5!|$WT~fUUYZIqHRAf1P2Tn#qER?6
z;lak!{rG$K%|6d#MB*@+)J0kUt}V(?5zn$b=ioe5J=Q_H@mB>m284*MrOepDhR3a6
zj;!_FEr>2a#=^s0Cqh}NYzWji{BV-Sam485uBU^lf56-*FmkJv68RK$-hMrHQq)d7
zpYLA2te7Vmw^b?t{v&8g6L^;hC|RzWd}Bn#am2(p_esQZQ~Ga(xW1SkQM|(>N_C=s
zJR~NHSokY`Dz)vo33}o{giH-({h#dT(I|=C;fjqNgYG_ya}WO%ZRU{Itlj)XBW0?I8h?u5Nk6Ias|g8
zLx_R*26FUHc;<}eYT1>S&JW-Zh>%p4AP?*6*x{%$j^HwIE^hDc`5%L}qMq1!%fZu@
zustHo^|4+%yBB$5EcF088|^*)fO~#-OJv|;T^drG!Xm=7g3o)1inveAY#9XojkAayWS#eblc$Q%iM6Ts2><3jACa#T*#YC@