|
什么是传染病动力学?numpy和matplotlib用python实现传染病模型SI模型SIS模型SIR模型SEIR模型 什么是传染病动力学?最近,在报道疫情的众多新闻中,相信大家也看到过一些来预测新型冠状病毒会导致感染肺炎的人数。你一定好奇,这个人数要怎么预测呢?预测人数又有什么用呢? 事实上,从学科方向来说,这类研究属于传染病动力学,就是用数学模型去描述传染病在人群中传播的规律,从而预测患病人数,进而指导政府制定措施和政策去控制传染病的传播。
/ g# c7 e' u$ p& U* n这类研究最早可追溯到18世纪Daniel Bernoulli对天花的研究,而我们今天所要介绍的SIR模型是1927年Kermack与McKendrick在为了研究伦敦黑死病而提出的,是传染病动力学中最基础的模型。 介绍了传染病模型的背景信息,不知道现在你对传染病模型更有兴趣,还是执着地对python更有兴趣呢?不论哪种,这篇文章会满足你所有的好奇心。 numpy和matplotlib首先,安装一下这节课我们需要使用的两个python包,numpy和matplotlib。, ^) o9 T& L& O
numpy-是python进行科学和矩阵运算最常用的包。 用numpy建立一维数组,存储和计算每天传染病人数的数据。 ) }7 K+ j G+ T6 Q( j
import numpy as np import matplotlib.pyplot as plt 用matplotlib绘制传染病人数随天数变化的曲线,给出模型预测人数变化的直观认识。 好啦,下面开始用python实现传染病模型吧。 用python实现传染病模型为了让大家能够更好地理解,我们先不直接说SIR模型,我们从最简单的开始。 SI模型首先想象这样一个场景,一个城市有 个人,假设没有人出生和死亡,忽然有一天有 个人感染了病毒成为了患者,如果每天每个患者能够有效传染 个人,那么第二天患病人数是多少呢?最简单的答案是: ,也就是说每天都会新增 个患者。那这样以来,在无限远的将来会有无穷多的人被感染,显然这是不合理的,那错在哪里?仔细思考,你一定发现了,已经患病的人就不能再被传染了,所以我们有必要把人群分为两类,易感者(S-susceptiable)和感染者(I-infective)(你猜的没错,这就是SIR中S和I的含义,R的含义之后介绍再讲)。为了之后方便计算我们记易感者和感染者在人群中的比例为 ,那么 。我们重新考虑上面的问题,顺便来个示意图: Image Name这样的话,每天新增的患者数为 ,也就是总传染人数乘以易感者所占的人群比例。
) F C8 \$ \! s& Y+ L6 Q a那么每天的感染者比例的增加量就是 。我们假设城市有一千万(N=10的7次方)人,每个患者每天接触感染每天0.8人(lamda=0.8),初始感染人数为45人(i0 = 45/N),我们来模拟70天(T=70)的情况。 # population
2 G* p5 ^/ E U# w# `) Q6 a0 T/ GN = 1e7 Q9 }% o2 w u& F" h6 K* C
# simuation Time / Day
' z4 @2 K3 o& H& \4 pT = 70
6 h }! R# ?/ x$ v; n# susceptiable ratio# x6 c6 a9 y1 w* ?/ v
s = np.zeros([T])
5 L$ t$ @+ B* E1 ^# infective ratio. @, q5 x$ w* w" c
i = np.zeros([T])
. U9 P7 `' G4 g& D: }# contact rate
/ o8 L& w$ w8 Q5 Q: `lamda = 0.8
( Q( ^5 f1 v/ _; L4 F( f. ~
4 D, d$ D5 G, a, d6 F0 s9 r: E# initial infective people) A+ {3 Q# V# H4 g* I, I
i[0] = 45.0 / N
% k$ [$ X1 ~7 D& Y/ y3 }9 O2 w
/ F/ ?; I1 ?! I* ~( Wfor t in range(T-1):0 Q/ F; p4 }6 P+ A9 h- T
i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t])
5 f. E: @+ h" i0 R6 H
2 q8 Q0 l7 |5 R2 V; \2 |- k2 L
, v0 v9 O% h" j% \
5 U( I+ r+ e& R, v; p相信其他语句大家都明白,新知识是这两行:
+ X" v* B( }# O: M% c. t% I- R6 d( U4 o7 s% M
* z( U1 }( r. |4 k* X
s = np.zeros([T])/ X7 \6 ]# f, a4 N& m' |7 g
i = np.zeros([T])
. Y* X8 U# L, b$ Z/ b( y
& B7 O( K3 q3 P% J3 A这两句话的意思是一样的,就是利用numpy(已被我们重新命名为np)的函数(zeros())来建立一个所有元素都是零的数组,而给的参数决定了这个数组的维度。比如:/ p% ~$ S3 t, L1 a: H) T) S0 S
' \$ t( j% v- e8 _a = np.zeros([2,3])1 j) Q! r, d% n, ^5 M& Q
a6 }7 Q( @" q: {. T" U3 X' m x
& S( { B$ K( ?' U2 I6 P
array([[0., 0., 0.],( Q7 o9 Q2 t: M& a2 h
[0., 0., 0.]])( y2 H! L8 a! n4 ~& N* H6 D
* P Q/ V$ P. h1 [, m0 B8 s
* X" S1 g3 S, s: n5 @
array([0., 0., 0., 0., 0.])% a, ?5 {- E' I; P
' u. D. C) C7 i
; ?& {1 L5 C1 S7 N类似的还有产生元素全部是1的数组的函数np.ones():
( `% @* L3 X8 f" k0 A( ?) p3 i$ I4 s0 y4 K |1 s+ X# m5 L/ N
a = np.ones([5])3 y" t: _& C' Y6 u3 V& _
a
8 }/ A' N$ g) k% d2 R2 ~, s7 J7 ?& r9 [/ d
array([1., 1., 1., 1., 1.])1 }/ h: y6 x$ J' k
. t" l: [+ H- L2 o2 V/ F( v. N
0 E W- F6 I6 P- R, ea = np.ones([2,3])# o0 ?: L' |+ l+ p5 d5 P' z
a
9 _) s7 l8 Y, l
" r9 N1 n3 a# [/ N: [! I
5 g S& K8 A+ n5 ?9 y9 V$ qarray([[1., 1., 1.],0 K0 {1 b3 Y+ m; h9 m
[1., 1., 1.]])
: o9 h c: o) A+ m. Z8 q! W5 p( i z/ {4 D! ]" c! \
) z0 B3 {% E9 X' A
plt.plot(i)* F6 p% O7 z" t# { K* [* C
: W! f1 D [ z q( s( l
1 E& L% S1 j' z* Q3 d3 o- _[<matplotlib.lines.Line2D at 0x7f0c2768d6d8>]- ~: |6 i3 F% j
7 N X: m# v1 x3 ^
: o, w# b4 K# G! I8 J; {
1 ?9 | C# P' P t8 b0 e1 ] ]
: Z1 M6 I3 o# e# ?( _1 O1 R
' k, f$ e2 c: q# n实现SI模型的核心代码是第三个cell的第11,12行:7 b" o7 w4 a- n+ g9 s' C
* [/ @! m, N K) s; |for t in range(T-1):
' r% l; k. c: I7 {) ~% r" ] i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t])2 K3 }" A/ Z6 k' [
: w O' J' D, b) }. L' w就是我们建立的数学模型,利用python的for循环语句累加迭代的方式把每天的增加量叠加到感染者比例上。 运行代码完成计算,我们利用matplotlib的pyplot来画出感染者的随天数的变化曲线: i) ?1 s7 n) l) A
fig, ax = plt.subplots(figsize=(8,4))( v' u/ m5 m0 l! L- s
ax.plot(i, c='r', lw=2)
& I' U( O) z$ aax.set_xlabel('Day',fontsize=20)
- ?( n8 B1 I/ r6 S* Kax.set_ylabel('Infective Ratio', fontsize=20)9 g9 q; N* P8 @6 v5 u" K2 \
ax.grid(1)" i+ U6 @! R- O6 @
plt.xticks(fontsize=20) d# s3 W6 X' r) E& B9 v5 w+ F9 Q, h& T
plt.yticks(fontsize=20);' d2 Z5 V" _: B( y) O( O
3 t6 h0 A9 A0 D0 T# }8 E
3 }7 T* S, G6 B$ \& A' g* g) j& Q![]()
/ E! C' a r! `+ l: q
1 ?& F% T6 y0 M1 }9 v+ w _从这个结果看到,大约在25天左右,全部人群都会变成感染者,感染率 。
r2 R6 |4 N) Q* Y q在程序中我们假设每天每个患者传染0.8个人,你可以改变lamda的值,观察全部人群感染的天数的变化。
, _1 l \% A+ T3 k4 ^) w认真思考你会知道,lamda的现实意义就是该城市的卫生水平,衡量的是消毒,隔离这些措施执行得怎么样。回到传染病模型,按照SI模型计算的结果,我们全人类都会患病,这好可怕!原因是我们忽略了一个很重要的因素,那就是我们有奋斗在一线的医护人员,我们会被治愈!所以SI模型只适合研究具有高传染风险又不能被治愈的病(比如HIV)。 但是对于其他病,我们是可以靠医疗和自身免疫系统康复的,那么紧接着的一个问题就是,被治愈后还会再被传染上嘛?根据这个问题的回答不同,我们有了两个不同的模型,SIR 和 SIS。现在可以揭晓,SIR的R的含义了,就是移出者(Removed),现实含义就是指被治愈后不会再被感染的人。而SIS表示治愈后仍然还是易感者。下面我们用python来分别实现这两个模型。 SIS模型为了实现这个模型,我们需要引入新的一个参数,治愈率 。好啦,先上我们的新示意图: Image Name和SI模型做比较,区别就是计算感染者的增加数时要减去被治愈的人数。* o5 e$ ?) P& y8 O" S
所以这时候每天的增加的感染者为: ,; _6 q$ `6 v @; K
增加的感染率为: 。% ~1 k5 n; W; `$ j
模型完成啦,修改python代码:. k+ y) t; ~6 f6 d# ? @
# susceptiable ratio* l" x3 W+ A) k3 H0 _
s = np.zeros([T])3 [' m4 A3 E. O$ e9 _
# infective ratio7 m) f6 B- I' G" W: [
i = np.zeros([T])+ n) Q D3 u# ]+ u
+ H/ |- D: @5 g0 z3 m4 u" O# contact rate# J( P; z% W+ [# A
lamda = 1.0; A) I: }6 s& A8 f7 m' x
# recover rate/ ?9 g+ B3 L3 K
gamma = 0.5 % T. @: {6 F+ R, t
# D6 t, x* D0 |' i' S# K
# initial infective people
! Q& G* y& V8 N7 i8 i2 Di[0] = 45.0 / N
8 o8 w* {5 ?3 y" t5 ?8 q$ a$ N7 e2 L& j) C5 ?/ _7 C( i8 l
for t in range(T-1):
% d/ J e2 x0 v1 H i[t + 1] = i[t] + i[t] * lamda * (1.0 - i[t]) - gamma*i[t]" @2 c6 l; O. x/ G) A
0 I1 Q! b+ I$ M" }# x& x8 o
9 L- u8 ]5 Y5 o) T4 ], d- [) m2 d+ x! D2 A1 R4 D+ l
运行代码,我们画出曲线(代码和SI模型的画图完全一样):9 z& a/ c8 H! }4 @. D1 K9 O0 i1 w7 }
6 }& E: X+ J9 f2 B5 D
fig, ax = plt.subplots(figsize=(8,4))
, |- ]* q3 \9 Q/ E" s+ yax.plot(i, c='r', lw=2), \) l- G( r6 d+ [% }, ]5 O+ m
ax.set_xlabel('Day',fontsize=20)+ m9 J) u& a7 L* [7 ~* w2 V
ax.set_ylabel('Infective Ratio', fontsize=20)2 b1 J9 `% {: ^6 C
ax.grid(1)
' a" `( ^+ N- z7 K# {/ B* splt.xticks(fontsize=20)* g, X! J. [- ~0 f
plt.yticks(fontsize=20);
8 O4 o+ e5 o4 h6 C4 Q
, O2 b! O+ l* x9 i3 n' ~ 6 n+ c1 p0 s: ~# X& s
q! a1 E& y6 h7 r2 j s
% T) O! x$ ?# }( G4 _ J" j行代码,我们画出曲线(代码和SI模型的画图完全一样)
' O2 W) U! T: x. F5 i/ F6 U" k7 q可以看到,达到最大感染率的时间退后10天左右,最后感染和治愈达到动态平衡,人群中有始终有一半的人感染着。所以,SIS模型适合研究具有传染性和反复性的流行病,比如常见流感。同样的,感兴趣的话,改变lamda和gamma的值,观察曲线的变化。和lamda不同的是,gamma的现实意义就是对这种疾病的治疗水平。 SIR模型加入了移出者,被治愈的病人不会再被传染,先上我们的新示意图: Image NameSIR 模型
8 s. E) |2 k' F3 ?注意到这里,人群被分成了三类,不再只有I和S,所以相比于之前的模型,我们需要找到新的约束关系。现在我们需要分别计算三种人每天的增加量了: ! P) i9 W" W& t& Z% o0 U4 [
- 易感者:每天都在被传染,所以一直在减少,减少量为被传染的人数:
- 感染者:增加了被感染的人,减少了治愈的人:
- 移出者:增加了治愈的人:
9 I+ T+ E+ S& v6 c7 N# a: H
建模完成,修改python代码,并且假设人群普遍易感,新型疾病,初始没有移出者。 2 z8 s/ ?5 S' X7 _( |( a
# population
h" o! M, @* L3 |2 Y! JN = 1e7 + 10 + 5 i0 t. n! H2 `) R
# simuation Time / Day8 c; Q) f' ?2 _! ]' m1 l( ?
T = 170
! U. i4 H' r- u# K' L U0 X* r# susceptiable ratio& m5 C! f6 V+ V6 O- k
s = np.zeros([T])
6 Y& S) N9 W( _5 H& F# t# infective ratio
9 I2 F3 [2 ~, L( E4 E p9 hi = np.zeros([T])
" I6 d2 Z2 J L# remove ratio
/ l z+ F, z' `; z0 s3 ~# Sr = np.zeros([T]). m% K) F) H: y# y
/ s" H% |6 T" R
# contact rate
2 ?$ N3 Z' z! a' g# jlamda = 0.25863 C1 U7 f* I7 q7 c5 ^: E- w" P$ V
# recover rate9 Y3 @! j# i' j7 X
gamma = 0.0821
, T2 A" ^+ X6 O3 m2 `& a9 F" ?8 G0 ? {7 P
# initial infective people" W, n7 O) o* @) t: l3 q! A
i[0] = 10.0 / N) |+ _$ P( @# T2 }
s[0] = 1e7 / N0 B1 N) }+ J0 o6 E8 t
for t in range(T-1):; h. l0 C+ N# R" }! g6 D
i[t + 1] = i[t] + i[t] * lamda * s[t] - gamma*i[t]2 G: R: f# ^4 a4 d# F& F7 m
s[t + 1] = s[t] - lamda * s[t] * i[t]1 ]' t: C$ T* Z
r[t + 1] = r[t] + gamma*i[t]& l: T ~) P0 u8 i2 p
4 ]5 j1 B! C1 H/ K* Z5 ~$ Rfig, ax = plt.subplots(figsize=(10,6))
* u* D. I6 `' t7 jax.plot(s, c='b', lw=2, label='S')8 N8 q% q, e9 i0 y' Z! U
ax.plot(i, c='r', lw=2, label='I'). v! M" Z8 O6 X
ax.plot(r, c='g', lw=2, label='R')
: {$ L/ p: O2 K9 pax.set_xlabel('Day',fontsize=20)& a$ H6 N' {/ k; D+ q& {) N
ax.set_ylabel('Infective Ratio', fontsize=20)
0 Y& b( _: C: a- h6 bax.grid(1)3 j% e; W1 S6 k8 g( {
plt.xticks(fontsize=20) ^8 Y9 ^: b5 M. R, t
plt.yticks(fontsize=20)% y3 U+ Y- P8 g% P' b5 K
plt.legend();1 W- Q; c* i ]
7 W( G4 d0 J1 `- y
: ~, D/ I1 d7 u$ x8 r
![]()
8 s7 y8 W# w4 |* c4 u# I3 a
0 O- b; q, A, p" l" t2 a6 ?5 r感染人数峰值发生在一个月左右,最大感染人数不到人群的20%, 但是最终人群的80%都会得此病(就是最终的移出者的比例)。SIR模型适合研究没有潜伏期的急性传染病,治疗后能够痊愈并具有抗病性。 到这里,虽然不准确,我们也可以先用SIR模型来分析一下此次疫情,武汉新型冠状病毒的传染病动力学! 模型有了,其实就是确定参数的问题。一开始就有人做了这个工作: Image Name于教授给的参数是参考了非典的, ,初始易感人数为一千万, 初始感染10人,初始移出者5人,那么我们的城市总人数 , 带入我们的模型得到结果:重现于教授的模型; p+ I: T6 ~: m6 j2 `& G
高峰和尾声日期的推测基本相符。 ' y. U7 ?+ @. G- [2 J. m, p
# susceptiable ratio, [, o; b0 A- [- p: A7 O5 G
s = np.zeros([T])! d- S% Q* \+ Q1 i4 S3 O a
# infective ratio# C9 y# O" z: l+ i& V
i = np.zeros([T])
2 [1 q- k4 a6 N5 C% Q( }# removed ratio
# l* u: p. Y$ Yr = np.zeros([T])
3 I# s4 M R7 }# C# k+ b1 m% x# `( D! E( v* i% F/ _7 O! {6 [
# birth ratio3 t, @- X1 I" a* e8 Z9 r
b = 20.0 / N
( ?4 W* w3 \6 }$ [# death ratio$ f! `8 n7 [* x0 t
d = 10.0 / N, K* x( P: m# j- S4 s
# e( P4 i( t4 v- v, v
# contact rate
1 y$ n+ X0 l9 k0 d6 q8 h$ gy = 1.5
, E V* y }, H6 U% ~# recover rate
/ M7 L2 X9 D. j+ \, Z' ?u = 0.8 # 1 / infective_period' ^, s" u- O% \) `, m3 z% y# m3 ]2 S
- }5 f1 J: G3 @; l& X( f# u# sigma = y / u
% E6 K$ {% g. n* [1 }2 ^! W
" p7 @1 G: }$ B# K' K# initial infective people/ J% J! T; M+ b" |* s7 x" ?9 O. t
i[0] = 45.0 / N
, v+ A5 j* i8 A& X0 ts[0] = 1 - i[0]
: V. g% Y1 i4 wfor t in range(T-1):
8 d4 V- E3 ]- d0 i' ~6 \( F i[t+1] = i[t] + i[t] * y * s[t] - u*i[t] - d*i[t]
% s6 A7 f. V- i9 f5 p s[t+1] = s[t] - y * s[t] * i[t] + b - d*s[t]
+ W' P; Z8 s% G& s" |' z& Z$ y/ Y5 ` r[t+1] = r[t] + u*i[t] - d*r[t] g) _/ p Z* f! s: Z! E8 ?
- ?8 R" \) D0 ] h4 Y$ E0 _+ y
plt.plot(i)3 C) ]. E0 o( a+ v& r6 @
plt.plot(s)
! w' I5 e+ R7 S; K8 ]plt.plot(r)* ?: Z& q$ g0 @5 J# u9 [; ]
plt.plot(np.diff(i),ls='--')' \1 ?7 F; k2 S
9 B7 t9 K+ ], r- n
0 f3 M) K/ y4 B) P[<matplotlib.lines.Line2D at 0x7f77796e8518>]
/ D4 `, z q9 {7 \$ Z1 r: w
& M- T8 W# T$ x) P4 y! B/ v+ w # D6 `3 ?5 O/ L1 ]' s( V
Q j6 m, }8 q' E# G/ S& {
SEIR模型但是,SIR模型和实际情况的出入会比较大,因为忽略了太多因素了,比如说潜伏期,比如说政策调控,药物,出生死亡等等。下面我们可以和前面一样,把潜伏期考虑进去,新增一个人群,叫潜伏者E(exposed): Image NameSEIR模型
1 [7 A* S9 J) d) j同样的我们需要计算各人群每天的增加量: S:每天减少:
6 n' p* l9 x- V' d7 ~( y1 TE:每天增加传染,减少发病: ; H9 S/ o. R p) g% Y6 k7 G
I:每天增加发病,减少治愈:
1 n+ e! |) N8 ]: E: ZR:每天增加治愈: & ?5 N" V# v& {, l
建模完成,修改我们的python程序,这里的 可以理解为潜伏期的倒数。给的4天。新型冠状病毒给目前临床的潜伏期是3-14天。9 t' T7 ^ a' q. x% b
# population
: U9 y( w) c( _' P) w3 S# [) bN = 1e7 + 10 + 5, a4 g ]# M7 o
# simuation Time / Day. S( W9 V8 Y( C- @
T = 170
0 _+ I$ q) y4 g+ i$ q4 t* N8 ~# susceptiable ratio4 v: C0 k0 i6 N; S3 |$ I$ `( w
s = np.zeros([T])3 E! v+ u! d5 y9 S& B% {
# exposed ratio1 _+ l1 s8 @* Q: b' R
e = np.zeros([T])
8 I5 W2 ]2 I" l. S z$ A0 a; k# Z# infective ratio
3 U0 B2 s. r- G2 g1 M, U- u: yi = np.zeros([T])
2 v) a: X* p- T0 _2 y4 d) Z# remove ratio
2 l. ^, f: I* P. d: J' H# er = np.zeros([T])! ]5 a! \9 D& F" v9 F
/ A: z& P1 I5 ]. c% m
# contact rate
) Q6 s+ [; h/ @5 w* Alamda = 0.5
" B6 c' e! Y7 V# recover rate
4 O" n4 x9 e. b* Jgamma = 0.0821$ L! W, [# N3 H' ~( B) W& Q
# exposed period
" R. }7 \) B( L6 ~% c; H3 Esigma = 1 / 4
# z) `; ?4 B, d) O: ]* S6 I+ K0 p0 o
# initial infective people
; S! ^5 }# r; N% s9 q1 qi[0] = 10.0 / N
. n/ `0 i# o u( N( X$ Xs[0] = 1e7 / N
, @0 g. n. }. M y" h4 X( ]e[0] = 40.0 / N. z# L! g" x& F/ k
for t in range(T-1):) y7 G4 h- D/ O. X/ J) j6 V
s[t + 1] = s[t] - lamda * s[t] * i[t]& |, C* e g* M; ]) ~/ N2 F
e[t + 1] = e[t] + lamda * s[t] * i[t] - sigma * e[t]
9 l2 Q6 R' h6 K- ]2 Q& h# _1 F i[t + 1] = i[t] + sigma * e[t] - gamma * i[t]) A. c' t5 h, m- |7 U
r[t + 1] = r[t] + gamma * i[t]
& W5 c2 B7 S3 _$ |0 j8 s) n& w# K3 w. p& U H9 I/ T8 |
) ?% S4 D( m6 F5 U6 wfig, ax = plt.subplots(figsize=(10,6))
, R# f: E5 Q9 u" k6 `# c7 Hax.plot(s, c='b', lw=2, label='S')
. m8 Z* K' p5 g x% B5 d, n" {9 vax.plot(e, c='orange', lw=2, label='E')/ A, w; h [& f& _/ b4 Z
ax.plot(i, c='r', lw=2, label='I')
$ ]+ w) W4 f# N1 Aax.plot(r, c='g', lw=2, label='R')1 u1 D% _- D4 W! h* z$ E
ax.set_xlabel('Day',fontsize=20)# ?3 n3 C0 }$ k: s. {: b
ax.set_ylabel('Infective Ratio', fontsize=20)* U: C7 n3 s6 b8 Q) R3 X
ax.grid(1) ]" X$ L( l6 F" o
plt.xticks(fontsize=20)
, q8 g# x( {& W" hplt.yticks(fontsize=20)9 `8 w. S6 P" Q) f
plt.legend();
6 ^8 L1 |# K# x+ {
/ @) B6 H4 m, ?$ i8 b3 J" P/ r9 \3 ~
![]()
+ j: ^* z/ y" i) @; F& V; h' o2 K( J$ K4 E: U
按照模型的结果,此次疫情可能真的要持续到 三四月份。这个接触率 真的非常影响表现,模型给的是个常数,但是由于政府措施的原因,这应该是个变化的值。
}" w) E7 O5 c2 w# @6 y; ^还有治愈率 也是。没有完美的模型,但是随着考虑因素的增多,就会越来越接近实际情况,从而指导政府的疫情方针政策的制定。# Q# K8 Y, b7 D! G
8 p, v5 r$ @) O8 T# v& B- d/ N/ ]5 M
# J n- @- m% {: u
5 R& r( V' s# @% ?, J3 L* C$ X7 b: L; F8 a* v
|