From ad6f84bb0ccdf657523055230f6d2b4af8383719 Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Fri, 24 May 2019 09:16:58 +0800 Subject: [PATCH 01/17] close #12345 finish dict --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e8e0b56..e067300 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ gitbook serve - [ ] Python 整数对象 - [ ] Python 字符串 对象 - [ ] Python List 对象 - - [ ] Python Dict 对象 + - [x] Python Dict 对象 - [ ] Python Set 对象 - [ ] 实现简版 Python - [ ] Python 虚拟机 From 8ef95a6dae267967bd829ef741ee23d7b19e95eb Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Fri, 24 May 2019 09:19:05 +0800 Subject: [PATCH 02/17] close #4 --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e067300..225ff9a 100644 --- a/README.md +++ b/README.md @@ -74,3 +74,6 @@ gitbook serve - [ ] Python 模块加载机制 - [ ] Python 多线程机制 - [ ] Python 内存管理机制 + + + From 962933f103eec4089032d1c6e253d2db2bca2ca8 Mon Sep 17 00:00:00 2001 From: istommao Date: Sat, 1 Jun 2019 15:37:20 +0800 Subject: [PATCH 03/17] close #5 --- objects/long-object.md | 213 +++++++++++++++++++++++++++-------- objects/longobject_x_add.png | Bin 0 -> 5445 bytes objects/longobject_x_sub.png | Bin 0 -> 6309 bytes 3 files changed, 165 insertions(+), 48 deletions(-) create mode 100644 objects/longobject_x_add.png create mode 100644 objects/longobject_x_sub.png diff --git a/objects/long-object.md b/objects/long-object.md index 1ffed04..6722b52 100644 --- a/objects/long-object.md +++ b/objects/long-object.md @@ -109,6 +109,107 @@ PyTypeObject PyLong_Type = { }; ``` +## 创建整数对象 + +从 PyLong_Type 可以看出,创建一个整数对象的入口函数为 long_new + +`源文件:`[Objects/clinic/longobject.c.h](https://github.com/python/cpython/blob/v3.7.0/Objects/clinic/longobject.c.h#L0) + +```c +// Objects/clinic/longobject.c.h +/*[clinic input] +preserve +[clinic start generated code]*/ + +static PyObject * +long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); + +static PyObject * +long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "base", NULL}; + static _PyArg_Parser _parser = {"|OO:int", _keywords, 0}; + PyObject *x = NULL; + PyObject *obase = NULL; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &x, &obase)) { + goto exit; + } + return_value = long_new_impl(type, x, obase); + +exit: + return return_value; +} +``` + +具体实现在 long_new_impl `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L4785) + +```c +// Objects/longobject.c + +/*[clinic input] +@classmethod +int.__new__ as long_new + x: object(c_default="NULL") = 0 + / + base as obase: object(c_default="NULL") = 10 +[clinic start generated code]*/ + +static PyObject * +long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase) +/*[clinic end generated code: output=e47cfe777ab0f24c input=81c98f418af9eb6f]*/ +{ + Py_ssize_t base; + + if (type != &PyLong_Type) + return long_subtype_new(type, x, obase); /* Wimp out */ + if (x == NULL) { + if (obase != NULL) { + PyErr_SetString(PyExc_TypeError, + "int() missing string argument"); + return NULL; + } + return PyLong_FromLong(0L); + } + if (obase == NULL) + return PyNumber_Long(x); + + base = PyNumber_AsSsize_t(obase, NULL); + if (base == -1 && PyErr_Occurred()) + return NULL; + if ((base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() base must be >= 2 and <= 36, or 0"); + return NULL; + } + + if (PyUnicode_Check(x)) + return PyLong_FromUnicodeObject(x, (int)base); + else if (PyByteArray_Check(x) || PyBytes_Check(x)) { + char *string; + if (PyByteArray_Check(x)) + string = PyByteArray_AS_STRING(x); + else + string = PyBytes_AS_STRING(x); + return _PyLong_FromBytes(string, Py_SIZE(x), (int)base); + } + else { + PyErr_SetString(PyExc_TypeError, + "int() can't convert non-string with explicit base"); + return NULL; + } +} +``` + +从 long_new_impl 函数可以看出有如下几种情况 + +- x == NULL 且 obase != NULL 调用 PyLong_FromLong +- obase 为NULL 调用 PyNumber_Long +- x 和 obase 都不为 NULL + - PyUnicode 调用PyLong_FromUnicodeObject,最终调用PyLong_FromString + - PyByteArray/PyBytes 调用_PyLong_FromBytes,最终调用PyLong_FromString ## 小整数对象 @@ -293,7 +394,7 @@ print(num) ## 整数对象的数值操作 -可以看到整数对象的数值操作较多,由于篇幅限制无法一一分析,这里只分析整数的部分方法 +可以看到整数对象的数值操作较多,由于篇幅限制无法一一分析,这里只分析整数的部分操作 `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L5341) @@ -340,13 +441,54 @@ static PyNumberMethods long_as_number = { ### 整数相加 -`源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L2990) +`源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L3081) ```c // Objects/longobject.c -/* Add the absolute values of two integers. */ +static PyObject * +long_add(PyLongObject *a, PyLongObject *b) +{ + PyLongObject *z; + + CHECK_BINOP(a, b); + + if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { + return PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b)); + } + if (Py_SIZE(a) < 0) { + if (Py_SIZE(b) < 0) { + z = x_add(a, b); + if (z != NULL) { + /* x_add received at least one multiple-digit int, + and thus z must be a multiple-digit int. + That also means z is not an element of + small_ints, so negating it in-place is safe. */ + assert(Py_REFCNT(z) == 1); + Py_SIZE(z) = -(Py_SIZE(z)); + } + } + else + z = x_sub(b, a); + } + else { + if (Py_SIZE(b) < 0) + z = x_sub(a, b); + else + z = x_add(a, b); + } + return (PyObject *)z; +} +``` + +可以看到整数的加法运算函数long_add根据 a、b的ob_size 又细分为两个函数 (x_add 和 x_sub) 做处理 + +`源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L2991) + +```c +// Objects/longobject.c +/* Add the absolute values of two integers. */ static PyLongObject * x_add(PyLongObject *a, PyLongObject *b) { @@ -379,6 +521,17 @@ x_add(PyLongObject *a, PyLongObject *b) z->ob_digit[i] = carry; return long_normalize(z); } +``` + +加法运算函数 x_add 从 ob_digit 数组的低位开始依次按位相加,carry做进位处理,然后处理a对象的高位数字,最后使用 long_normalize 函数调整 ob_size,确保ob_digit[abs(ob_size)-1]不为零,这与普通四则运算的加法运算相同,只不过进位单元不同而已 + +![longobject x_add](longobject_x_add.png) + + +`源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L3025) + +```c +// Objects/longobject.c /* Subtract the absolute values of two integers. */ @@ -423,7 +576,7 @@ x_sub(PyLongObject *a, PyLongObject *b) borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; z->ob_digit[i] = borrow & PyLong_MASK; borrow >>= PyLong_SHIFT; - borrow &= 1; /* Keep only one sign bit 只保留一位符号位 */ + borrow &= 1; /* Keep only one sign bit */ } for (; i < size_a; ++i) { borrow = a->ob_digit[i] - borrow; @@ -437,50 +590,10 @@ x_sub(PyLongObject *a, PyLongObject *b) } return long_normalize(z); } - -static PyObject * -long_add(PyLongObject *a, PyLongObject *b) -{ - PyLongObject *z; - - CHECK_BINOP(a, b); - - if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { - return PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b)); - } - if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) { - z = x_add(a, b); - if (z != NULL) { - /* x_add received at least one multiple-digit int, - and thus z must be a multiple-digit int. - That also means z is not an element of - small_ints, so negating it in-place is safe. */ - assert(Py_REFCNT(z) == 1); - Py_SIZE(z) = -(Py_SIZE(z)); - } - } - else - z = x_sub(b, a); - } - else { - if (Py_SIZE(b) < 0) - z = x_sub(a, b); - else - z = x_add(a, b); - } - return (PyObject *)z; -} ``` -可以看到整数的加法运算函数long_add根据 a、b的ob_size 又细分为两个函数做处理 x_add 和 x_sub - -加法运算函数 x_add 从 ob_digit 数组的低位开始依次按位相加,carry做进位处理, -然后做处理a对象的高位数字,最后使用 long_normalize 函数调整 ob_size,确保ob_digit[abs(ob_size)-1]不为零,其过程大致如下图 - -![longobject x_add](longobject_x_add.png) - -减法运算函数 x_sub 的过程大致如下图 +与普通四则运算减法相同,数不够大则向高一位借位, +减法运算函数 x_sub 的示例图如下,注:PyLong_SHIFT为30 ![longobject x_sub](longobject_x_sub.png) @@ -514,7 +627,11 @@ long_mul(PyLongObject *a, PyLongObject *b) } ``` -k_mul函数 [源文件]( +k_mul函数是一种快速乘法 [源文件]( https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L3268) -`k_mul`函数是一种快速乘法[Karatsuba算法](https://www.wikiwand.com/zh-hans/Karatsuba算法)的实现 +> Karatsuba的算法主要是用于两个大数的乘法,极大提高了运算效率,相较于普通乘法降低了复杂度,并在其中运用了递归的思想。 +> 基本的原理和做法是将位数很多的两个大数x和y分成位数较少的数,每个数都是原来x和y位数的一半。 +> 这样处理之后,简化为做三次乘法,并附带少量的加法操作和移位操作。 + +具体可以看wiki [Karatsuba算法](https://www.wikiwand.com/zh-hans/Karatsuba算法)的实现 diff --git a/objects/longobject_x_add.png b/objects/longobject_x_add.png new file mode 100644 index 0000000000000000000000000000000000000000..63cb695fa810b2a8df5f44302a12c26dbbace5f9 GIT binary patch literal 5445 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 literal 0 HcmV?d00001 diff --git a/objects/longobject_x_sub.png b/objects/longobject_x_sub.png new file mode 100644 index 0000000000000000000000000000000000000000..e500b1257e068ac1c95183747e23715fa535ba94 GIT binary patch literal 6309 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 US{6!k`{dOIx<)#cTE9N|FHNB%DF6Tf literal 0 HcmV?d00001 From af8d8c3491e2fe67d45521fe70ba75539301c2d6 Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Tue, 4 Jun 2019 19:23:46 +0800 Subject: [PATCH 04/17] Add setobject --- objects/python_set.md | 0 objects/python_set.png | Bin 0 -> 52635 bytes objects/set_insert_nine.png | Bin 0 -> 69113 bytes objects/set_insert_one.png | Bin 0 -> 52879 bytes objects/set_insert_two.png | Bin 0 -> 53960 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 objects/python_set.md create mode 100644 objects/python_set.png create mode 100644 objects/set_insert_nine.png create mode 100644 objects/set_insert_one.png create mode 100644 objects/set_insert_two.png diff --git a/objects/python_set.md b/objects/python_set.md new file mode 100644 index 0000000..e69de29 diff --git a/objects/python_set.png b/objects/python_set.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd762808f586e3a83715c9c19ece21d2543289c GIT binary patch literal 52635 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%0D_2_de%f>B(yQBG4`zLDif?8u%+Gj5 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ĉ@pGjttgGCET#It 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 S$WOsP6UR+4Ix=>a|NjGA8DMGv literal 0 HcmV?d00001 diff --git a/objects/set_insert_one.png b/objects/set_insert_one.png new file mode 100644 index 0000000000000000000000000000000000000000..15ae74da694db6f7e77f9284e93546bf2a4b34fc GIT binary patch literal 52879 zcma%j2RPSn+xJh}+DSA>LuN)Agcd49WG8z^B4yK3$vPbrK zKNtO<`@P@yexCQekK=#b4e|Ybuj@L`&pI!c3({xSuHLqqLZPfZcUDx6LZMcqP^cPK zF2|oxCw=>Y|66+f)H(T;_@Dhs-G}%+gQb|VpB*CdRMO- znpqA|XNyoMyC~;GPs&>d_kOprmNJ;m85$_p^}g&czUkxzW(lseH?(4=3Q=FSCB?F< z8XLv@iCW1VpXUEc@sdLGD>?a^uXG<7*K#MX+?4DUu$Qky_viST*TG@lOL@H?Hiz}t zCLFn5aXoZ8U8drl#kfG10DDB0VdMtEkacOQ?om;CTIW~OGBJ5ZM;my1*fc4t#?!4> z@nDn7KAS)$$zi_Z{vCRboF!#5%8#E+Chg@O(K)C7v*>X~xhMI89+eWw%aQ8N8&0ic zzPI62#~x?DzrPGPx0-|e5&oRVhgPvIaIo`<2A}m{Yc=Ejg+HBmlFZsi^)PwAuyBa` z_9Mf!N*Yyf%{1gLUgV`;BNZydaO~KJQ=ZfKS4SPD_+P(%t(NT=BJRGeD&maism3tD z8;_Q+-NqW`G(T%~>h$TM;o;r*M)&S5U9x1!;GaKHVy<-e?%${TCUfEhr6yV?+V;E*I{ljary33P^^C=e;x3UKCMlOm!ia zCM!5vD)5vayTT*i_SvDu_hY>wFlkdkUSnfWPhCQadAs=6*O$xM3S4895*Q_)94KgR z4pq;zH6QtTz9Lk(j3XiAjzmE!T2fS06rcR~h3BW1ZQ8UcK*T{1?_}w+Wj{JP?ny`I=jKvv-@bj{Tx;%K zHl^2UMj@&TODem(*v*e8NIJT`*n1EE)uw>C*=ZdEg9ko7n-vumzkU10qg%Wo)UIFP z{<@u|XP6vBu?ENIXHxid{`9?Vk;`^;5ck+|F4OkU#845FQC0XdtghR(Lys&vOE+%c z?)v13Qr0(hb#=9Li)EDk`}Y@mGF3j>!tu^}Xm^pv&iuN%C#$!xv-VL_Q!@x!vSN9} zV{0vXzwu_xj$H~431JYn<;Neskc*O-Y@=Ct;Gtb~LqkK({i(^xd73=W>Uvzi#N=wW zo}8sK;KVlD?{g@<-mrP|X$gtd2M!$A%fj+FB;>rk zy%63Cr76SaV9U{qa&ottF0CDDpq5Wi4=FA_+t%J*)orM#D!qqulh6-Jfm*4vH@)=Y@E zPaCB*{MSeOVtnYJetGfRfe@=^t-O1yQq5XI72{QZba$70|6qk9N55t{KCoD+Qj zk(nOoQOR7lkNe_(sx6Yk?6#cgTQ1NZ)6me^v17-#cjkLOJv~I-`nxu^wJ@eXSH^+Uo2FNqI3xx#QZ}-J`H5gdsG?fmicp$*EHN&7L?lE zlzy--K||?kI)_G<&4wzI*@PqOakQ$lQbuW%(NVobteffk(}EGcqz-_BG(} zztZI27I@HL-QDGD!%>iQb#-~{#!Q5Sg-a?bSa^B8xw9sg*xA`()0*GBsgI9?eNglM z#uekQae-#NJ}l?8tHQ;02wJXOzkWUW{u_A!T3a=%zv6qe zwzk?k%#7B^oai6rIPv7b9MM3C#jphf0wj7y7=@AEY5zciuhO@eax&+4_y%-@5f)# zFaD**iL1+K7k+ta<-v1W`xe{F2K~o*5)18TC3E@S|J;DYn#+`E9{c#*&DG4&1E3vKS^I`Znr!1t}b-DT{eN+$&sQvtNyca;Y%vT)#;3H{P0m+ zewWHmqTp@=?TeR1XE|N=CGGY9_*i+9r1rUm-zciM>uDJoP3B1B%&j-RxWP|Cp+kr9 zh@!r}{^C#jf40^?aUJ_Al~?`kpMjhbc9c9JtNtb}EJN^7^E)3uijLYkcuyC{=1JbE zG8B!H^E(@t?EgeHz7S0WwUSRWhw}7@nYvWO=7skq^OROmFF-L?51RsgbSDP~2miKD zI`95(rug9k9Id9fD9AWE2ju>fxvc2i)u zIoxqBE)7J{?vOkwxqrRQ$i&5y^6z^n`Ll7_dQ;!PK$S>ockw-*)n?`&mq>7at?_?SW$62) zNTl6T@N!m9tI>ybt{e-P$Sb4Vovb9yUheA)plC@+S(EZ(r79hjqeqX@zP}h<^IS1D zDK(W-?sIA?KjRlO^TKN5w0(3vMrD$ZUKxa?rQP_qZ}^`<))ry^rq!(f|683_@$U)I zVquFDO_Dr!PHVWMg!9syxYP%`7ru?COCmvD(M2Ub`*F&{(Pt+nCpT{1oZo1ceZJ>w zyz3X4$>GkJOK%TgLrjkC+q;*?_zSBeaKmoytxi*;M!!)Bf6ZO*sz|aP(r#*MqDRXW z5fK64;V? z$jWbMP_3WC4`wSmCLrML>np0Nx{Z4InpXU?19BpZ2fuzuYKtO}$>i53l_e!7qvW0| zZWR$Q;NMnKQj(k3RwaE#w(-dp)R#!rG-LS~Ip^o6A8gvbT{7Eo_S*+5?l*7Vi1jBt zyWaovXJMR5$|E&-=LZiqZ`w4RllMwGL{R>fybEe|YkNEOiIJb5%q=X!Wh2B<+pA+P z?)T@qBo1uln>9Dl?rHD9ux9zw!=|NSPIKpgMg01f?R5HC&d}^M??A_?ysKaV{eH~; za_|O6E3nZyY3alDZ%pcwm&{+wssjYdk38qY`0Xe9MDOe@A)vM1aI^~rkne`=M`Hm>31PyqFmI%XtP(I?R9c8iFFVgV20q`y{6 z&-)Z~gaDuC&z~Ensp@}vT7WKz*1c_dtnZ?S=fj7Z6~O{)7=;4*8sAc1`}LU_&}?-F z-OH0FPjYHx1p4T_9x3^zOLvuR1rYceEv|@t#Cp>2QjUKudr+Hy4{9fRZq0I-Fr^g41 z%F1YfPyjJYumnS6W8x82SliQBTE7+zKvAoK<|w=Ietx6srMIwOhUTURe4aj)@MIJ= ztWVy@b?J?KMT_^IGiRlx3GNR*?i31KmTXebr(YTR3Hu>2C1npD8)&uaow*KP{wct5 zCc%Czo(1|_=XE(bxvaxMN6c9E?!AX~Owle_?c=a<jy zd0vEtF#$_B{`$6XGC!uoe58rZ=+gcDHC_@&&^4+O(7Gnu$?5(YhErV?A?B8r@?(8X z={_Dik5y+m*y%N5Q&jc*k>K_9@*>|DKki8PIL^+ClXsVwha7tXMkLR^MZQs@P9P=Ti$A)d&Buq>=y{0q10d0$)IFUoGv(3G5cT4kPNetadCm8bjbBKU|0068{ zV-uq@$n7)7`N=LOoY?gBF=W$)ki&{(rTwrY1;Mdwh2e!?gherVwms9f9h6Zo_a&i z#CEP(o=?5iaRT@+-MoD{O1S8mGc}oZR`^^+cb3tdm5|UL>#g_YQ1SqJu8vjWcAV}z zLJAfLQFm?ZRtn0?9u}7SWS3iZ%LxeyO#pkZTD!KOw$^WA!kR@YASdlgT>wBa&edLK z=G*Vy9mNs49}*J6CjuaDX!x=u{+3dLx>&qoP{&}ym4xSVF=u6D3{ZaDwjc2T4{^cI z@(B&CI5v=>^Eleom8Qs($zXQs56UX-B}t7It}xW~nb5 z;gt0$29P@@I(%dTj#(YR8iE&}U?{s=F&oj#ZM0L+QWKa8wH}C=(s6)(dx&$WdB%SgA-qI{c6v#VS*>bhjaEdy?L)Vyse;8#1C*XZwB*E)4OcgNW& zUegAC6v)qp{POXteyFq8dcJa@FoknAJ(G+1^(AIAmbU!qAy?FRvb4bX^;r(b{QdpW z4(~(cxINx%w;tygB;%H+=X#(0GCwDV+VO@(RW_W8tsO?C;BXqH?){c@cYb!j2^4=2 z)mrw$P1Ah|H+sGfVR2d^8AwEFx8~fQn4YeAetHFP!L6oOH}P+*t*v?NC$14VFD136 z_LV{eUM#2DJFmgPYjoV|09c~|62*hEV%?4$VD-+jCkL^4wRLpP z$;fm~4`dslmqbQInRiv}L=6sx=3a>I8zP!Sw?xL(v?+3MjqV#o4i>La(gN%wv z!aAM3y>1U4tl;J4mB&`d=`v^BJ8<|tBnK>v@9jFQe2!l$Y6|2B)aC2ou_!=iB_-Rz zcL89%9zVW=e-76115kqW1NlJI{Z3#PsQ{kaBVCo$>2K%O?l|hja8N%{w`5aXT-=2i zd3%s*3i=H71_p*0p}R{jyuErE?KCGcGsbT(ZuT{#n$*ip_O`YXRy~qt*XgHZjsI5n?io;&1f^;)8YK_lscb`~t+ z@Dyje8m#qaWtgYCyZf-mbI|c5!>ZkdZVdSau3OP9PePBHo3Sze@-jE~?utMjttHog zmOr>zs+GqMeBQ67kT}GaBE%l*`9+4;Pm^;0oP4 zv+Brm-x?c_-)vdr146I0IpV5oYDgi&@r!)%f^I^nB0^~Y#Z229pvHb(R}Wl%AIZ7* z!UhyDoPGvA-Iah!okdJeq!wPOdp(3wyM)KAS?G;fO9g;OH%gp_!=Ehxk#VYNt4{>h zs%AS1QxdZ01iihzOlSpj!@UK^rX+wIRi7KpiJ9I!@Cnfr@%LtE&;D zF(33dAF*xNj;_~kO17XPyi`l)W3nI2)frE^Qg;CAq*TRe*?N2+Z-c-^HpKIw-nkZU zVG?Ka;iE^|sQBL+8XiA=s@ghobX;VA4d6TEWC7bzRu2ykQE_pL=`mB=vECAVxIoA# z{r&w!Q$FXz0`3!$YIW_}EgWhZ%oTjtb8wx0Ed-fP0vY6Ueqs5PEP*yHGX?@ zb2BAQEqzm(>UmAgU0%~BRd^MCmA6WUd&%pyhnkG{T70RD{A z6TsJ7Z0!Q0qV{3`EVCGS?{r8|NlEGc+UdTf+23yw z&dD|v`{*B6BEaiE>qA?%ZZ+UEiT3l`0*IEWt`RA{b~&~2jVj|eMeceA24`$-ZCyUv zHVpp;h%-)m>gDCN`wv&BBY?gBP+P%hU*i)IhpB*GyN1{KZIAv3O=l5nu`pW23{Ff; z?B-S zq1j=_XgWIm?EFiM$_Irlu9OF_8EE&2Su$e&oD#J!O=X3 zP5teS>2@O{qbT7WvQoQu?_LS?R$BT9ii_XawMAO8$7|ZHG!f`3MX!twd^Qhd4US7* zL&N(8^#@%JR1tU&xKyk%RCs7`khM>1Q8_wuLE9N^5E_+mQWllZ+#g$q7?Cgte^+zF*=#6d#-=RDqu^4h9R)AUeeEUApJsK_Bp%Bh`!R2wmuuD(8Z@d#Ow?8%=&_G9%1ahKk%a~IEt0QajQE%ux&J}?*5hP!Xy z9syEsKR!RXo;!1N6PkC|uc`=TWn~D|gz*8)D0v*S9^AEGI`|n1A|#7teiC|{K4|6N zpO~6@>Y$#c%5`_e`kyFu$|@?)s|=;u7OlG!gGxS7N|Bkt(*RC;QWn)Gy`0V5r2f>W z8f``;l)qX}Z9R}V9w20s%y;+3fKx~Um=D_XGEF=dtPTPXDS3H$P-_yZ31s~8`ttT$ z^K;|b1hs}7v(o0@rjl;4kAmmZM2Ga{)?mDa+Tnpx=jH943+BZ`zoxhG?Rt<@ZSC+) zWd#M!`y~Cne0=hu1p!?yu`u|kUlB}PCqnFJCWcC_u^1}vE!pxPtS>4pU7e|JCa3It z|Gu`7kqW1CElSiotO)cEz0c21eu-1reCg7ql<6%|Xv+l4!vWlW*hCXOE!C(-JTzrN z_h6+CHPrIM4@LDWE-r3O?+V?63LPjWAtj}oduN%%Nxvi1es9h25h%gJc69NIvGyKt zc3fb%MK&#=r>8H5NQQr@`R8}7L=f7i&z<&fNjjFj-@Ji4*c+Q|x^@CA)@RtH$SGgW zuqKl0n&o%pb_pIkw)LqQye7P6Mo^lIj}lSip+MsU5VHU}0QTpjo4aYu|E0omXAGW7 z8fBC4RE>XugGfpm7G(%9bTcF4fki1@lwnYmCKe>F?dQ+?U|$q~DjfheaDdipt^c`TO_4`9iE-MJJB*f7cF!=s-`yJ=o+vonIM$3_x4JOi;E|HV*mcmoEl3E z|K?HD@u5*Ty`6AByUM?jcXqfX&g8ULi6&w zw*iHLS&Pfd$W-@Kj4k;7J>*D>{pRA?gbC<0rCpo%ODCGOhzu7x;502? zw_{~T1-%0f8_^Aubc%)xwrYU^GQ9|eeTJI2NJDKZ|0D5^nwkXhErgu3g$ zzp%ZK39Ep+2>VAoy2jhjFKS2oj~}-IvtePqxbaSG9RdW4S%99eUlKIJf`fNJQt=&w zDK9B0$!OU;A{2MNd2X8Kl4>YsCIa z;_Sa1_rvkOEDZ5@MGhM24u`8>;~1P~hE|}(fB7PR>eMO9OUS=BZ{92&i&aWUhRnNb z{A)JQ%GH*vwH?hYzuMZu-AZuCP+_QGPJ{a8;dkf@DVn)UfQ=JAR*qotB5JxX#MT0z z_ycpZRce4C2c`;J{@Q@8w*+kbsDQxGpE`{QxftJ($8QsJGK*fyvuDlE*%7-Crh<@A zFi`0;#aI_t*Zl9_XT2-B+k>r!OxSv-mA+ibZyHGc->nz_kG6y6@IUJw=W3paSKK=3 zAjR%i+7XaZiBAGL3EsPvs52r{zxG6(SAUMpz7uMb42sb0raYE?`@|;gf8;I00Xsic zIjs_}sH3HI8`uTh4GnHpi1Y&#+lC!SuTiiEm6hqwKjnW8T*Il7d~X>I-GwA=F;Z-^ zvyY=b!^%s6W(be9;5PLNq6R$S*7ynbEwMvVvdn(+Rjn~RqhbOO(KY90 zCfyi?pF$$o^6e)SQ-DMdoE7Q~TeqG$b?VMA!>+@J6(?1&IYIw+jZeOsZomBQ8kL!u znO-Ag8hTIw$c8xCRj(8{;K3esniCou8?*fV#RYY0_|uV=M2G2{kXmCnmC+OozrQ~O z_iqMr0bxpRZf;9PUdqR8LL@;VS2;#*Uq(g-dH~;pbvvS$RTKbSWMjwnmcO_*Lv#cj@Q|d?)lWJ~*(QQMnM;w9r@40?{LU%!Cdf zK1^Jjqaz)^eig%y@~w}{2;@gEogC>>`EWBndHC64vL(Ei!#l6Ey81EjDM=il>zzh9 zhkTEHaSPyqs6)_uAkQts67Z;aWPqB1VxqmRT(_>Uq-2$olarnk$|wYT%d7y%SzS;W zzSY-PLFlDGv0S-&^^#|R^d{fm`+?hv2^2zX-Kt^ljqcmU5daL}7xv*s&wVI0NKRmN zhT!f#Or~4xR>to_gMiI~vab!M_W7uw&eHwncPoJ>`2=E6rv^pE!iCO<=*1 z%7~XkH9zlGJ3D^hXWxo%sYVyGvPKk_X0)Jq#l-CmI1?qe7z&BNLFPC9^2@t0p~_G> zMSm@l6%>*sDHTBp$7wRFZmzFaVH;arCb_t}L%m*lU5h_^L!Q(=Ipxmp>&7{Gx4C%UBOA-V=4Tmf|bPp=eWt;fGx`E`X-{JAwMz&(8LbU?^KY9$fN z3Y&m|N0Wm3q}bpz`=^c=8R#xRB#gV>dVR2;C_Tqo?HZdUe3lr=>t%h%)SjUkyk={4MhS zckhGx3qbf7?2u48=oQWgM-XYU*ozs$<7zOms7gR4KBMZrV6We@osL6uHfen04&%Vv z-@ovq%jThxk%J6He|qW!?8f3s^0th>y8PkrA>%I>MCRc(@n8As1}p|I*`>;`11c!K zt%OkuSS4hWTTKd7P}YmVWtpb3*cVBWX#F^PHR)H^yQCjKejFfdcR15-Tpvc#iT-lm zgoK0=V>=2Cup85Hbrto@i_y{){4x~#Du`Br0^OhAhnij> zSZT|j0kT7?wdijW5WMkQ6e$~mEvFuV`y+&f<4YL?8zABg`Rsx>*a7>Y2#8d_!=^by z!VOgsMW-7pf{v^QIWjRZA zT<8=lDk_d1JEmi5>W;!MD=TZrzm3vakUsACCM|6rnjO5D&Ght!$!?RN3)mj{pFXXn zSXo(7MCNC%&&`a;aB^{VLxezC*oS`(702SwZ-p09flE%nCnJ`v*QGB4M~|W`k1Z*> zoNl4Fjo&Z_(D9w^A9mC@3aRCA(A2>`qWbXXQlV+88P-X|BT#KhAso>kxf-0@WNU4G z6zJA^#%GF~*J;jPzdYb18WU6sh}J>)(x>Pm9By~Hz!V=BBs}}H`y)u z4ISSPOmf1Y*@SZf>={wl z%4+{tMD$-7QlQV!U-7r#xjaLOA&>_$Aa$Zn(K>9e=jGzvmVzkr($Ek5+7;uJPXana z84ZVQ$Wr-D?Y*T77P`~*PvLg6&+(UzbdG@7k*FFDaOn~{($CR~OZj@nx3WOEYJ+GE ztLNG0U>tyF_FZwk?1FfV*I6 zpMG*fa3=(Dd{bm}iLA}o#lL#-!9(R_QWM{!Nkfc?Mvo{xjE-4dUF};5X;gyQ$Inj; zdc7|L7l==9UmxB%JZ5p5aX)Aoct7&$lpRP+u0K9=;@Y)Di-C?yW|?9rQOE-yfnHE? zL>w6{yZ~_N9Dp_Ow4aRwfOaTx#igaEqHBhbISEWH0r3+Q+=icl!m0wX5}&fv5m^=3 zBcFTz5VKG*c`-xP#xR2B+7;#$3NrlEWO~49J}4msU>}J{BpzpGXZ`xXOG$Rbd2FD& z+h{oB@slT8b8~Yi8&Le>K8wIM0<>ed%!d1!e9snN%s8dp0_!ayN2DWD!LxtxM?R2S z3LrI_Z#hsX$f+(l?cct60f|7B0*@6H6Y~xYl?KYA2{u}c!-enlMGEf}Z9y4#b~*N# zUnN}SHzhQ;210ntFCCIw)cmR=5A;z9;n;g5Khn^06W7T)Y@0df;&vvX?s!txU$s=P z=HhXkLs(YgMIZ}AV+!x$A05qWy4(jJ_!0s>b%*!we}G@Wu3dfEwYjQFw*HBi*Rzbb z?8t$^wOxf*iY6VI`ZhV)_7~TkzkS}I?xKP+#8u)J`j#49jmJ!ZK7n-YZ`@ca76!LzKTfDUh(?DX-4*2yu4^noqG) zNzqRNkU}HFhFjVSd;nd{87H(I`Zjj@P_daY;G{4lMCx5YD>y>Pl4HNi zHh>Hyeyh0s4`r}(uPO{w3OU}f&#bl ze^%1ZSvs1-(g4E!^1Hbm%d$Q54EcwjInuc5X=&x&TebNg+aIt+Y4uAus>#N+3*5We zZa|oSoBO6c1M^T(&cZNqnxDJ(;6Zy&4^2k}KLgO*?%lpoHB6}6ykPL~$k%mbby&A# zIiP`%t&0+nZa4lqx#faFD^MzIZ*R{>0mG>dK4#_7;yCT@d3=tZ)cfSC-v#&iFQ(T= zd+Iy^nUjrbSdg1B%bH{XJr73i36A^LiRvGBhS^=NvxW*gUq0qJJ+nV#W-5Czv2Y$?&Xrm!ntvlioxs8q6DZrorZs9w++S>8}r*1c0 zqT=G@Bz`Cm4zb5`a!%+8!K4Sq46o@%{HYxl2#GgAeu$W{KMp}s(DGLfiLRhD5U@Ek zKHdew#w;kP8pvRGL0wFk2`Yk^h`5j)T+OVWoZtbab7~Kwh6e6;`2DLh|J!tjnCG7_ z!aB=%pz3yZft%=DxgrUn{n3{*=vV1BBP`f)%M_m=X*LQxouh+D`?YJ=PDE4<_9SE{ z6Yt41l%;7@~l-k8s1vRjYo?j<D-5DLV)Kj@}!sZ40fdlJM z^pX3P29xlcC0zur=1kY|`I8Y<0iz5%cVbj#-~4pTyzjW2p04g7L@VMiB3kf@)*Lw@ z2%vXS`FU|9+K#RITkZI|V%Xzg!T_A`)+=Jj;+B2m_Cv-*8bFWI$NQU{5(L{>v7V6_ z<5)!M^a4zUd{BOGX_TcBNA@PdWANok>I!*VlAxKL9zO^VmN%1wRF$Mg)i|uwK|p$O;#U-B+0b#Fgm}4-O=y> zaC>CF9>J7Ddt~qX@z<`}HO}CtMW`&=9x1{g)@_}g`)CY(weSWaBlkkfCviaRvXA-s z5pbmzo|N%6a?i@ntG7UT(T5?9-U)F*q2ctV0({wBB@Kryh!WuO7N6+^o(VX>-Dc$H z^IGGiq$DhUF;iP5O#kP!XyJ6t&H z&$}cD?uasRdn?OaQYRFepgCf{paBtC3-0_@HV^Cf9UUFlF!X~0Q-lX{#y)f1%3b*B z(|Mzj)XRSr-T!6^>k)|vjq`n%T*w;x>18r0AP1B+E-YN${$F8Z4nDq3w}`Zk{L+>f zryoFh~SWJjh!Gv5~$_M|A8~bnLVhhW0Y9)y<|CM9@ zy9l?RwHD|StOA+1dB`IBzrJ1E@~3D&hDTCgZAe{(Dv1xS&^iY{1e(qX|Os7?REV_w1p@Xq>ZHZg;FaJG;{BH96?{(10R=cPQ}pAE01i zP)QQFA1C{{UYWn!4uMU#a6VbvZJ;k3K?Vhgg+u2Ig?S^kb5PKBs517N9*ZCBVRAkY z=$7{f;W^yRy_KuUDi@7yoZ*Net8*~ClesZMflwkyhMy_4WCU)gumvFws3dCUQcs5= zQiAc4C7N(>b@lbxr=eJ5f`sIXOAkY{Br_aMd0p61C$3WYd3&Ffm#4k)`-^PDB^4E3 zgNhv#Fr|EmJ}U37F)O^1|ADj&(g!4DjOjTd`hxmOWPw-_bOJ;+2%Kb&C<<~mTVcGy z85cw}g9=5y?PQm5Wqt#_d*OpI=28)OXck;e)3dhn|KEPZm*05<%lZGS%i9!@>?PRV zx%w=WeXuQ~#y9cF@hIKE0cgovI21dOF?8xUig()yaSj!OLeMb{cg8KeX9{^LKP7e9 z2AL4SEpT)sqE1CrZGgC(=S;I|%^J=`Cr}uXiB@XhI&iB}sYZmdUutBFASA-lSB8&= z7C_8c;>qBs67LO7DG`dP&ys#E#;y!k1DTU8x#8;D3x+QH|7-ArOo2G3B&Md?Ywky0 zU_~0+Ly0Ik50cg1yH~V+D+7ZI&NjQBME%zk0~w^Sz)e6tro6QwOKY2%$>{5|AYl~+ zL4^d_h)5t21U1tFacyMkO)X4}joGm>Ffz2Yw6yq|?Ev@85y$^W3_EO+gG}u$1aFBj z4FP~+jrh3H=Vw&Fq~*Z^J{WNWjFgS7Ej4{0Ch!E%V7;l`fBb%-s;_aSSMy zFu6*oitSK!SWK~PX@sceCo7%kG06ujX_-Y>kA$?e;#gxt1OD=ENC=q-A$b~LA>+E& z?kOn;Df?wYKUP-C1TtK=vRa{uv<&=WYS0Z5*TSYozMKpM{%^9F-$eKX2G};x)1M`g zmaY&hw3>yJ*rw42QO@RV7pWBf;Y0%fVM9!p1Sw!BQaGe0b~DCl5Rhva^@!^17g!RzajdMIwI3k*iHPa1{~g zYwPY_m4kC>)R4+Xf;kR-cy=VO;gypBp!<>LUGPDH>&ciYd=(efc*WIxvKgrA!&`nV zRu3T~FlUQv*IMz_Bw0;j-dokJZ-Wba0cQ3$XO@8s7Xa%bnfSuOb!SJ#6ij)uwRAe)A8}~lkk7BN6N#FGu;9?KM2DF|1(4$ z0tyr*7?ZaU>aLIek_DgrwU~{`o}UYXIS8rG8evIBBek}nVy?#vj~gB-T$Kmu(I4dz znZR>uYCDjb#F6B&9@HcueZ>DuknKHAAv@rL_l6u&E=VE< zcu7op+mWkM$N}KfA48Q6hM~WHy=S%bBH^5I6{^zf0&X<|MFd*SD=9fw9~u}~f;>nm z&;+YSRz~tHO1xC?QE&YC7Tx6>p7HTqd&J#{`%fY51Mdves(zRH@WzXfV(dO19xs{Wv%Vl; zr72eySN5ZD6+NX@OQw?Ygwd&ixC2v?Ef%e2rv5d{WVmrgvnrpg2XuiwQ-g(1WWz^ zj?XZ-2Ikbn;Q`=qX(A5JqGMM3Y74AW9mu+fj!WCT?wOe!0az3>+RDU~FtY<+4qNc8 zS<4Ifp+p}BSS0ErpqMiPM<~5gL5JNTm2FiPdNi*DyYhfWR{8!g`%@scX#X8(AWeuW z659t@0w^LK@)f4sCa*60JLniGguO0tSiYpLwp)(bVWx4 zv~BbixfK2LckbRrm_pIf2@6jK5#Zwa?3-9rKv>z}HLe=sG0PZQPBL6@>zNN6@IXtK z#oB`PoQPLVBf(LOL%)0X?%Mwy1;>xin4g=Lhs*J9UT2`9UFZE=k!Q9(i;wW8FR#DK zX}6R`zgj6_%4KXC5&mT?!kDAhS?)@FTCJ*GOq9G4rx?dx{-rL$tC(HmSRM!NJvcJG z$FnKH+nHXsdwSBkBeyAiJfqU?XZhZ)=Ia%iR-R}x)oE9h&?H9$4=tuym@YgMRMbyl zNK}(Xri80V2O}E?6PB~8GlIFnPUkZX!<^>})6FbW#i{XTEm;Whj5~ihzX-PXvt8I3 z`xm_YtO%irrXwd~@aP7BD1s7CjHKm( zcu?;m;f_=aCj<+z`IqS0zIgxePJt$ma;o#zp~=#cGGs4R$Q0%kOksW{hD-w(%pVvs z$%p+r{HB!;*K^HKI*h#^oY}|1qW|I9$CN@6=_GU-g&(&f4B}P-3-mJp!sBp^7ZOge z_HYk^Ir@tf%Vt=D#B_m-E#b#r02m&4=n5UX-)czAVBLP(X<}=QAvftJ{cef4aWO_7 z&)SQLqy2@C{RZc@g9dUovb75{1{nyT*={N5pX&O#671Lo^~&H4<0|=Q$h3o zlK1K9Y^TXnxI%0t@_*0~85?t~6YQ`^C?Zg$Z{ak8qO!?Fu0$(m0mCyeFvyzv&4Jw1 zx%1}Y=w!Z;&1w6#` zjvh8XfxX}n2XFkAhjCR1@B5mC1y~E_*iJ$!O@v>G%qQ>$F!{Q5>s00_7~mR4$Ig&Y zS=f9ly=Arpcqm}v11Tlw2yGBeNreHg55Vigg40dEfB&9Ouavg*3AYSvA2!ugR_F}O zFuuqI6(mA}dof6N*fm?2h2a2gtO|?<%w4#_KE=sQ7$%}4!h)C5Clme>KV4Ry(^O#4 z6?kNdFY|4b5Qe1>SFc_rVVb`uf(23p+VCo*Nbe}a0`2lm}rO$k!nxS0H#wx zB6zmBO9WCtj=<%WO%4W1LDY#l$nuw$U$`Zx2t;Op!ScX2xO?IHSg#5?^{D7zQQkP>13zZ*tRWI+GIeBtPw zS(U2s>)a=nz1q_CMIV-vvL8aI>1ul49cQkxxVpg`KJc_PbEu$i}@;FAm(W*Q_HQddU`9T zd)5MQzPb9n6ftap>p$1Pt1BCRQ54?F6DUPwEkJ7wN&*N)z-SEYf9@aF@ciGiaZ9#i z`{^))ng)-RJd%hi{li$$ zhA$nnSBJYx%G6g}02GG{fK+fp&_8vIV?0S$(Vj{PCkwA=oBMJsAT;L}vD?Enc>|?L zQek3{q(V+ZOzsd~08GVQkva-F@fz8or1K$-j&x-)kcme`gpRtBq|hFpl8=x($pi-w zH<^bf_p+cWb=|04*ngtybQN-z^g~=LfPTt+`aYt%)ZOx1uHi!>rcEvs0!DYkT`!0Q z*j(mX?5Rtulh|9az+_%7R*?$}9GU{Vn7Vsl@xT|ikjK*F+-h{?N>I_Ejg^-QS9_*k z-XyT_@5Tn4^+5hEUY>}bQZ2DN3lPGoawc(ryEU2$u;Hfw=MWhQh*feROiOj1zrM3ay%q z_~OBCv+?ry=h7(U5|#vxU2~0Oa+hQw!PehlE)^N8XmYp^cP3*sU_Pb(TxF=0R3xE| zz7UT1Q5<&B%a^Q(>;RGDR+>|6b%y+W$d!}feApyjO5KYC3G*w{wf7BU;o}ip{sE4m zg&{k&4>#T6tn)!wC-ePywN$tXg@!1#X#OP7cw%a;Ws&>#A|$&Ba}!Gkq+YX)|E!?G zLj7oq^5Rh3-GUSA%PPC%ZZ72ndW-LTn6RBcX3{s~QXoJX3NXh?Et;P ztYB^>V8^h}V*i>yx9s;Lg+iwKN#}Z#iXQfv{c4%Ee%RqV0r*_keS!XnNgy5qRB!{8 zPx9r2x{JxW=WtN{w$?7vkol9#!gbOxB!Pp7-V1e>46D_f=%Z$+fkBq(98k|FhCV=f z=QJ;Z>Uq%-nfqLLJ$?=-!MMlfWg_hib+&A1 zKOf(4pnA~!9eA!N`joPYxP%05;*!wA%>^;L@CNfI!RRH)C@m0*G;AFfz{f`?&-2ns zxBsc7qaW`Os)g8C2{;y%%!)s?QRr@oFhBI>$|DeCN5F5ZeoEl+xrw{LVBU`(=V6U( zAmt>xkxxnjmxv4V^V1@`itx@7GRBG`K-%JG1k*^~2^IsortXhCXF9#8$VkM`(S{`A z!1{+Ucg*WJW388siByb(y1JjAS}BQB0u*{iS9dSM>XCpUl%@|>>oe75Aidri^*D{j zN_-NrrkR`0{bEOvlS8w|^e5f~`fNMQq(W#1C|sLSo8g_g;1&kVsF5@)${p@`CDK(I{((BK77UrjxYt6oN!*WA^UkQ8zN4ZYF)8j#5rsxUc~_)dg+6FGnK!$qW(s-S2D2m=lj3 z+7NU$tgs&pEbI*2#5Qxn(2$iR)u6sxFqL2RtjI%J!XfMxE9Ffw@%nitsN=#ZW2+pFQ$ag z&zvcf#;m6FHenftmZEg7X|c|^mrWUF4AWUJy_a+EX_;wNX}pVz3RhIl9yx&wSOA<9 z6gtc%fmm3=MfsRDRrJpim!eP#H?grRt02*?=sj2(J6WJZ3uXqeE7g z(i;D^SsO15@R;ZNPpQr_+(J}J(ru7oWDyN^#c0m48pOG91Xf3`U%O`I$_u~eUlL>m zZsn?R4T=TFttxoTIBW9-1NeM?ytw%d3gu%{ zMzmUOuvrRr`X6VmhnAq)ddhYLNyB25`Ob(D7kr#f$l^_CG%*cift0v=eZ5>=C13ZS zq}{yPr*jBLk7Q3lI0*;G9%2Reg*?3K(-PbE{ zMsJUDXk(4^A)Qme9Z4Y68ZrmCLDM6pODnxKK%fS{TeXm;L@unsGax%a!rJLiQK4Kp zkFg_|N{$Ce0EwMp-!z zPk3R1ME}w}29~5lh0bBG;p|0Q549039&dv!Ka{FdLK=1?=HD-SB$Ocb;_IUUV-`sR zw#sG8m*WBf(74h!1QWx1>KsDymyGt(;~Fn7$3HBP=K-+TrV)T_4Wx^~9%?7oOhWUp z{Pj7v?dw`Hc()6=LF`(p?u3ZDcc}rIbRa&KmK=+ydKe#X>d%X|O9n%`aW4o!dyy_5 zazTWH0d+QI+C6D6^2Ftskc>(PJl4QTAdCpq9s#QJ_#)0wOw;Q@cE`}emb1s}$E^*< z%%Od7s-~W0V3tE}O5BqX_RsY<3AH$|UylkmFydg6>qiXv z!{uT^UkR^d7IplSmyl-Abk`8*ha`U>elO`B-zA7!MG@;Fxq71UsW1-Ub|@mv0|pX( zf@BQu{}4EK3=eHopB$C!go*$b{3ZU<6SzzlvEMM6Bnr-j#idkdPcZc<>jj&;ySiR{ zqkucjAkYY#(?0}f2Mi(ZJ0uCdo4v}eU6?Y)va#~jliK76>e!;F7hJm#feU!{YtCbRR%G2=AiBp{ZDJsEhv(Z$67mt`6#?SA08GIqVTxCDh4=&Yd>?i#QfqCvQ3zu%gbx6Y?S_vI zWOxu5#I>T948nd(+9URew!}9Kh!9s`YGQVqt`TSk3|JeR7%2?ma3Qf@4E!0`*<(4> zCYCkbe~gTBLCL{9A_?lyWjirv3eTV`L9`J1;U@zCd<++@O6o<$?@wF7e6P4t-MZ-a zx$#{fZ^_C-TpTc@z}v{>BEUT;flI2Lx{o25k7OC#Tz7~b#H_$i!LpM{Pcox`qa7m~ zv7Fq#dE!Ov1#FYj&-c&FpDp=q($r3FfJ9=39yi>8=9gK7L9%WA@#Fan^YwvdVH8o$ zxkPVpsbw`FOoTJzoOB^5Nk)g^rx7u*b^dCC*AV?PxM`(Jl@Y7dTUL&!C>^{9$cO~) zAleWGCj|LLFL;>5S3u>i>iI+H6~66eI=UCZ-({qw3*nRkTw^HIKjt+)sxQ|ie^@6e zh|X}z>_|^f=f$MVuGyslixOt3nhFI29|lj4PqpS!L$ybQF(LUAVsP<_S9teM;Y1O? z1Y3+3Jrv7!A0>wDLb!r3&Q>9Z1F#5d_XV1A#z@7n^w;YnE1hF8E{doO8=%JH#p$-6CUVhQUgkG0&yR3 z((rUTUSR3VM`sX}B!UeVRwdPNBYFxT0=X1|KwrEoOwgBF`t=!+$Sc-nYOGHZ91&Fw z{k!uU+UcCvM zY;2%K24Q;eI(-PSWK0fje!2cZL^&b>t%$w<@Zm~aDk4p6SEL8)+n1V!S7VzY(vCU*eH6lD8L>$vJjhi)Agh&@*%03;RiCkae<+x8B83H&M zxbtmRKA{VJo$N?>T!@5e@&z7+MG9Vw4sflzdLPD(d^vVPXfD8HGhz{}N_T+b;IBji zI7y@fXC@oJRsd}z&Ku!{U%%1;NMim@8j*DZ0q}2+9y^990tSo;BFXy$dk_;MXBnQZ z?9T5amu}*^9KM317|{nJ23qjJeQyW_`0s4NzTAXyPS}6g0sCLbt^&VvfTuudKK;3=14?`s3LgW17yO5M6@#j*NCbww@AQfWlRzvC3t8xMB zhN?`BFTIni`3y=DCaX6g!+|BPPrn{ry%D(=TH=Ps*0L+T=bJMGmwpB=6DX+QB{F9Z zN`_Zj1J^^3ReCwP2I@Z!IFY1qwa_L=i+BO#LN&w@+F+&T8uC{sXdLg1+Z7qM@o>;5 zGCYcFeei+E?cmp^AJZ_aKf@$2$t@7?7iq)wj6w_flZG^!vl=hEGRK=E&`#llsFnxH zA!V~621BBxFyEI7Iqt*=L4icimhEHQX{^sf&*^{T(>voO-AYXmN#fL2l}t$g!8|)K zh&HHE;OiHb9~H(t#@M^L9f0LC9wrbjSA>(B{0zZ1fer@j{DV{fco4+PM=IHHrtP! zhkwQOQy5MZu08Udn!}riPF1*DACeQIp9FDA7)+RxDJb+M;;KVCmCdj=*L&%BA5S`h zQCHO_#|~MvBr@5E?L35Z0&aK9!FxF?CDnn0C1bK4Wo~q!B@9h(7^UQR(gIL?GEjH$ zhLu$%KhtykfYQJ;w}XBR98f+4T!+a{2$s0w~=#+$m)31ymvj z>3WyLx+{e);dr4VkR3(_f1JK^=MJk%a%4gHQ2?R;)!KW&^}M(7|KDs`p^%lbQW4pk zhLN2%id4wnLS!UK5-M3Cl?JKg7$H$nGNK~0$VwfR?D2nIaqiza_wT-cD#bdW{xAe7zYy+n@4K-<_6TcdcSZ-P+XF+6>!OGGjFY7GG#R zX!Qtc692U3J{|5@#Ba@&r=6}$oC`>p6yO8JJcTCoITdMo%X{26$CW;C`TlAj6y9pq z!6r~-N;1Dm_=Q4H8nJdR1w|%dB>42ABJ{fpmM(3trIlRZG6rab(l(rqBz=5e>W}Ow zD{N!NzX|T9UqXcol2A}oBm^j7KxSY>$kA6kUqOtl@}_accWtvE<x@DUf^ykP7PJITfmjB3!IOI1sT zT{NeGVJ*KWgKX{h5 zC5WI9gxd$@I^I1xA>C`w*2V_ta^kHQ#sGscW^HP7avIHfy4fSzQFyfDcITCk*iQg3 z{Sn?0vy~cxQ$l-HOClM`?3fJ8Q520^J@7Xa3HfMK-)9h!57zBw**#nXoJQo*A4+O? zc{BJWVKaN$34efY}Bm`CcpnCP_hVhDxWgu}*Ob6%cz7I8GR zU;6iOgC@_VE$p-EgWhi$(*4IqI*dN!U{@Vvb-;iD%uk3bN4iB5*lz?YeHo@C(+QQ1 zV6p)7O1e*gRod3^K|h~kp-1l!L}e)qBKBM~$(TzYt@~iBudh`}>?dtXJAOhGN(_`W z328?M$IwUm`liIWjT<)#dfVoEyGvwp&d1a%n;YIddA8u$fv|x@EGi2T?cbo9qN(pk z5WH@&O2u&VH{*U7(fC!T_#nyNpc5HIxDcls=xb?4foM8?jmUNhT|AM;sPIh|jf6az zlEdjUNXZiBoviQ2KU5^lynVQduf~*1#ZfUA4g*al;!+Yoo`YmvJYtK!a#D>$`4Rs{B>t5sjmgIHu2asy@ z$cTpYSd>)l0Yw<@F8%rA$(;A>;6vN$W^_YU)%WJbV!2@+ZS6;=Yeuny8{0_w)#H_r zPe-B3HtR8L(+J1^U)+UiC$o)Q4hidK3^PZXM=ua#iGP$*REYxpxNb>h-^6CG>|eK(y>{uInB^dr0*JqC>wEW4?5L51#0{k z(7Cpe#_+AprghWT?N9gwy(#7Sm12XIhSwDl9=srirmyhrMI(0zm^=Mp0wBUp%0PpK z1;%n$ftbc{lW;Vb{S7e}zHA`?&#+zd9p;n^w283Tsduv$ry`1)^Cg(6ku`A8F|3ty>-GFM?h) zewo9?6>mL&nHv_XfvuBjCg~)I4aZi1<4&5tipQUeh8NAKnr%}v_zK3zfb(Hw9RWAWW zsr0%cO5_57WOAJlnvFnJBvp~&SanwzMdS?z=L0+J9C<$nQyo+_ml;E=exyM~)c8Z| zQ@R0+Kc$dGFT}a=AG^kK?(^HZU7so2T7Jbs;vFZn+x*9g;VunmH48wHO;$|jwm0yyDQ2lwJ=ftm0=B_quc=$`c@S8WcbF>@R zd&Q*ZlV~Xg!Bkfd%C%^C(2`A?~Y4m-phF>JU^- zLd_Z?G~N2BY4yNiA;`mkeY5wR=r_?8tzrMLjvC_mf$ zmky<-h!Y@>+>xYm4xyN9(JHFfn3xol=}ep7hvP4mFl7W1tg&*7n!>>0l3ObU0MpvP{?}dw|0C1?TF7C!q5$Z4)m z_6zi}-T&Q07mM3}8xvg-CU7j#9PrJ$2~YzGD?I?SQ$s98! zD^I1(!vO|};Y&mTa|GaU6?gYXff6jF#0}3|PT7bQVT^0y(jrSNu)dn7{T`S9(SMGe z=)P5$%>OT1Q9LI^yxd#C^KX^wcv`^{eVJLcFYzkL>WO^=d?NH#ULdY9N%G5 ztV0S+jViQFI4U8VfS;rn&eZAUf3_x=l7Pn3O3C~tCkz<9deZ&-fLNEQy`*+xE@su6 zT%%vtWWtKX?c1_>e=5>^=q1rkw;s5X;p}nfbYz(phRh27rY9M5F;gls{z}xKkK{B6 za_Vh>I{-B*)k{_MX&g6N79I_QIrq9kyL8VEq3{Yi#o&?`{HTZO<0 zC?Ow8!2|{d_|ga9lw^=Lrx(_2GA122C3S%i%?mDe7_&zqepj;li9R-BvPt?>d_uV_ z@p@5EbyUNi+-LrtU*RCJm?Reg?sau7a}4M*CH?4xkX^b{WwaE=U`1H&aBFBsPqZKV zc$lZnm=QkbBA9|$1w+39Ik#;v`4B> ztc|Iy1Voq8D>KuFLd;<0`ryk8kh%Ao!z@V}<%_e6pR~L9i zltYESKSevuW8229b~(lB;`4 zLxM61Ne=3r4q~$=u_C9EvTBlsgwyG${n$dGiUDTn31IH3w&5di@KODHYK8rK@w0Pnu^u!3X`V+^U{#}fq2-h{k|0C@);rwFz8|0 zecCpGsp#1|L0R+Br&2x0h`U*YH3l3c8>AJCN(H|H zG*?PPKwi;V2;Hba!{BYwm7^iZG2lzJgT`Ks#N-Yl-hlYi@r5%|2ueKBOA+rxqw88i zCnugRz^ytN*O?Su`LV=j@7}#B3oZ-YCu0UE0e-%pd=SOTQ}(PeHzJ!tK7(*#NGe(v z*)9f*%IW!pHwwU7J~(7Ps-V;7&P}J@#$uOZn^N)w4h3|WvnTw3kmI?Zf0U7IqDD$? z?#IEamj1HQOSJAq7lF`^#|-raeA;r4yn6`vNAXqp6G4r4>@Zxiy1N>DPzU1=_Sn9a{V1PN5b4vBQRIj)uq9Ol#ZE z{wNJ?)u#mohU9<49IVH;Z{NNY z{A_S}DWd+X-!o5I=vbUegGs?VD2d~*cWQ9a$4!hLME3eQz+qtV%c8%^$-gUL|3?Yg z%O-PiI{Gr0?{SkK<}c*S$+vy=Y6OuAv-ULbe=?qv29`JA%lK5)MLK1~UN$&rW^Km+ zRCV{C1!6_w@prWm>gd4(G0B{(?yWiCz(mYJ2;w~nRkB|qsEpv*8k|h*0mvsUVR(Q1 z_&T3%Q$Y%??v%cZv8ig5PWR`$Aaf>`rncZ2BiRAw?9#IlZ;N>54dEi?knd(=-H#tX zgwZ2@Yxkwg2`0Qd_Ptp*D=_fp>+{#fkMD2c%dIj$bu$x92IEP$fyoNfpFe{yI`PLJ zH&0FpH4`_(EvlW$9=_RQMLPHYn78M~l3_KAW(8%wm@}PAF0*!YkJ=LsZ;X4i=TD#T zS>?VfbF9aG{k-zO3s9q*2IbbVQCk2Pg|JkxkT!09N==(K_4a=#+=E4h$hdx{^|t`l z$99=NY3iM=)IELU`@zwkb=9j30XXQMO~(5%jrN|pxLd{-WZ!-wart;O5(8)Km}TOs z$ycg8wu(g5HDaU#cR6jNI!c=wXxu=K=ATBcyk6#mSw}cngH6uMi(_$8jT)YM<%(nf zIXy1Z)OGKCEXFM2sO7Qd06B5HA6RW~HE^ZsiqG~-)Pv*GmO|NDIaLNTRcHMp)3fQK zLPM&K$BZ8;dS>j+khO1n5!T^29Bpzi+K7J$I`O z8^$L-@ek7=W*MX#92>n4{2(9GUN&c(uDSEmU{E?o3Iy3PNZu5Rn{;UkmVsSb1GwUF zx_VSIqP5~JfW}`C;e_HO7G%Xajgn<9B=b*PJMAfFPcBON6?QhiEcQUv`{BZmFSB9b zl7Rop&gy*5K|MG>*47cKw0m)P)<}$gAm|NQWmg&z?RxCx&c8Il86}C!(6T%60+nXsvhVJg}dcHD#M*^t%l(rjV#moW` zO6Yg5{;P5@R!+!eo z=_!6wK!(DguY14huTIH$p6V-IOOBfp+ocE#hkuRnfas@EbK;?e;!2)cp$`eS5*0C* zeMcmvKDqc54<6A7%Jd+~ghBaEzQ4SuRSZ>oR6jdit$Fiw?$B8J!%kDq_Mk5Ou)xMuh@! znoi-BJy7Z}cqEI=cyl%@K^E1OoTWe)OU=|iTqH*NlY+3G)b#W0mXS`KtF6awHq@OI+)1@9_8f1;@Y znrYLg&u%`zL@oq@-7e!7%jF>;GbbUHt-nH{|Y}Zne?{Lt&4wFFplv$AGc$ z3d(V~h>F44bu|Z(=Pjkqv5?|Gme4SqPc9L_y|R$SAVGgk!T42`k4H3k3wzBbE}Hg* z3l?nmsIROPa(e`ip%lkB?a(5m`;YkbZlig(hZL+RDyiW%kR$~r<)oIKwM|xLN);6a z$5SW;@bM)eT@+g{{+iY4^*n2s(sGn-l<2Yq;VA9|OCpt7rfMQo$m7Jmuw9DENu9~R zMrr&Sw*cq6vR@9Aa%P`rKlB#0sIy{LY}s@>_+@D%td4)v%Wm{}a_ZNWB-GG>&jXju zGzelO3ZbiW-_fyMS6?_V{D1RMf>ZosI%dr1(e3^*9Yay0I1%eNVZX=ikm3#@@+LiaRFdO-QgRcGhVTS5c9SsVX z_LL)0B|~Ot5D(37k0m1z22=a;xau9~4k<@6VH{;K!WLRXLpWG?auK!N4{$}t0*oNg zl=txqJPCgKBV@SAxC1j6ZNp7rd^u8w@L0ptD_p*!VXHsVbGkLfvqog!rPj&jej`iJu2lqz#`}0KPx{s{K5D& zvplhxiO2}~bpbPr0GKKJsxDwS6VySQISFD$+&z7e0;W&be6O%lNafBV2e^^@sdrrx zYT2`BTLxrZ zmnEwFw2<>dx<&mGHg>-$M^OZN6iadU=F`9kD#EEz0yy;DyLZy5#nA>7HMQL-%gWfy zIZ?o%otx!6rhzb*;n(FKo>oWmASE1=H1I#8S?LKpG9AM1Zlr}bVwS4nhe4-xz&Z!k zhyJ44@8J{xx|b$a_5hey8$&jJPN!X@4bBIPV0L6H6k6P(LQ{p@O9HU$Foq8SUtl+g zucv2Cj{MaRD>RKu=7MbivNmE{43wIGF(MCH9mNraZx{h$5#L#scacQF1jaB(BA_c( zAY8%Y73!S?K-Kq;-qxnfA8!5~!z2?gu5lxWDE@8cOd&Evkg0BnIJ|3ruxX{g@v2Q~ zff_=rgCIOI69OD5J3+)6nr8Lj+pnzRd&hNaj3kWaYFl9mOHr6WmhXeFhFmBf;6-g6 z_zWJ*DH>mR&MF5z4_A%`9NuLVVlX|`#cG?8=!LXLaAesneVZCOcILEno1XfP(G{iF zt@Id2<2h8&0;K^)7wm?}xJ6$<%eQ0teV8t4W07q;*<~YQm-UiV3T{gG<;%N5K4{sW zLu@A!Pb4T!jJ9D@q|(9ZL(B77J=S)P@7h|e)?h+!qyeIK_k)|;iv}4ti&s{j!a}40uIT8z}FC{ z3;{4Hl?rRzskHF0upi+iH9K4>r&8DEjjAWni78d8Peu7#w)@wZ+9>X%><|ch8D$Zb z3fV_`uMSQUiUL6Y=m*1Er9bbVD?f2G{X>JNPi(9m8&)?_F?rZXEzrD&-k8Q8Z>2BN zH_e!$TM_OtYExL@j)+b!hb^6t`^VUR*<<6fU!sw8p#F z1x>pUTvT?}@x_3bYf8F*v^mf>L&ZYBe)QFLJ?1}d3B;H6<2+zh@y|NJetQg@loeBf z$5UQRuwA7U*_x6q6Y3hyc;|mdJoTy|DNB)-78` zfB(tR?Rx?oWoOblwT6DxA7GR$eXjMSNg>dz{r>F9m!_4gu7GK`d3hd`viK)+v|=m6 z@2C@H*T=_~H-6TyZ(o66Kn;w^xL$WwPwJvC)^gb$}lf8SfaQ1YQ~*A z@z&8SGCg*E8RS8(m&Jk8-x8N})BisG@4vElC9W_Zi`S8{@sW=8qj7xYpZ8a|EAo%u zfj)AV_$RAzP0PxkGG1Abw59T=MvQA|UHMZDUwc*6{q*K%)fkUdv|7! zVI{RKs%utrUpsh){FuR*0k+*2lfzXEvG=`mZ^|K^chE8l_YE61_^mROzwYFx>z{7+ z#5^jSVRE%WEwnZcu_^EAsHezo!p$ms_fC*c3C;-WRT_C6NnUuhN5n22G>tVBPhY$U zJ63aIgpp>ojVjP${qEd7Qjwt&yF2hltl~xJe7zT;YxUe+U$^jfeXUVvs@<2=$n?bL zPE#C?+@9ISZ-mZLbu*I(T`db8uuWAU{TdD|z^8s%SXdp?7UeXpJDMAZ;8I39+eTGa zhx0#-B)Rm>rCo1Myjndw>r0CD)_?tL@z{D12ImGdwERsc=|yovX%l|2sU zIRrV_@!+M9^WcNLpssNB*!kT<5E$mDyXTFb@@!{f8`LkTIzBp~R zzCP;bfBa<;6qsnZxc$zy88l?go6^lVl^FM)w|Rq1>!wr!e0VeKPQ-7+ZqAG&?t2?vT0iAhlc9MScrtCUgq= zvc5+nmD)9`O)Vxr%MJjA0&?8(xt$!72{wIB7%ZkN*nZ6sy>_oxp5QgaF3zu$)uIbdPS2@MFUn>QcWT2I<*Jt4mE}&`O4{IF^!+9336o;6%#DmTE_FaP7|@E7+lan@vnY z524jUk{8zP4tiRx!_DQJ)}fOfuOn$x#*(Rmsw$)q=k_jS^C?r{^z+q|o~^Ut)F_fL z|1$`xi%_?l?N7N{N1b>6EtW|*+Y_NurSgDO9>SX$jjk3hLUhoKI%X#Rg)(z;cj7or zHe->~WYjeFoOOG8hstp8p`v0qB-HHn=!p|^^+jyZ>$!Xj4T*^Z zkc%nkLz3xvl|2mCAw@_AXGZ0m41g}T9!^zTRaurB0b?p-no!HjxC+Rr*uDOlSYBUD z0g;}D07pr2&5-z3s4|vP0p_;mgZEsP?r(W|6UncABd=5X9^nxYMNP}I{ymk-|F@V} zRxr@gv4=Qp`_KZbM-3S!*esFqUD=o(K;2U^hz4=bt6mp1))hT<9etBxj-$*$I1 zC~A1Ifr~v?nHQUE<2>o|E+B#3mi4ZDf|tBA8&dhwT9w(;d@PE@W9H{X^$U)>sd%dw zC9P>Fo0gq$Jg|BFq%E7T;?}L2`2GF0Lva<3>F*;d_Ka^}V$myn&*{ut9Xq<6>h8Eg za@KucEETlXejo)6l#eUanE2D)=<#FH`oY!U#v?`qma2Zi{Y( z9~f=pH2ZvqyG9efJU4IrhdTdzzqqbNy~oo{jGN%4UYB}weN>ceF6)ZD1Jn891Ibnp zB^p>_hQ?I>?}~R%mBd{MVdZq%BaybEOR!t>*-0u|VB=vJCrov6@*uW|A)2M7rD#NW z^4s{EHf+*l6EfMupvYHQ>c@j6PsO#4!AbP?RA6$4&}3~rKQn!DFIdZ~*RJult7Ug( zeR>no{|(#PY~4RYOU?RM(9Otpb+Ps%-C5()i}X4@VGepC=*{&gO}Dn{pK~;07(43d z0v0S=HjGJB#yYEk(WCLK0X$3`H`hra*2N+w;)o16H2&4yyJE0GSGSr_B1`FTMD`+> zifHEEAM-Vs#`R&PKz+rZeuC{&rdC?9%GjF2s;TPU)}aJkgm1;m!E1veTxX8;q zn5EETF5#J(nQCjlm3m@R*x=-!P4620{P8^@c;v{QY8o2)Uq1e+zfmR6N&Xw9ObVQ8 zLO0&AGmk(gu3E>|16H(Q+^@6ri+o22w8jYbv--#E*mbh*^0)UiFMNK{Li5VSp0PBz zv1@;>DgMew(+Myd`8l}HLc`Uc@;&MPiIB!ahPbO3zPdYc*sx7Nj!hYNE`XWT8a&v( zZnLgK00t&v9S?G3GH>4T$FBavXBFjAE#Uapgp*MKg4OSVC#~XU#w0a2&O6q0iZi4& zF;zWpB?^=^5fx$yC#y;Pf`j#W!z+CJ6helF;UN_YSFIjB?zVCD4?XE*ZRV!><8Aop zAT3f}$j*s254KXr*Y+^fg#JC(=nr+L?BRS!YeJ33o6ENz_#A$4EBOrWb2Arr-Zyd9 z*FdTiZ?Yh0yC&*@wrDc6H{N=5quJSBqYGDDz7-p3pie5%^3DPI;Q_BHEaoWv^VKw~ zNnjxYsPhPl5^v3#3uDDqhJvr=J?tjS%E~C-Z0B4c@dFdO zt5kt_w%9)FbHcnw&6#tOp_p63UkzR}`JCH$ZB;ZcYhrtu1lru5l|Hcn7l}e_9T;Oy zjJ+?gz&Bz6-pcd+pWC!HDGGTtWB&B%6JO6wWh!rq!}Y8;f+V64?&jjA`e@TI6O&ns zE%5e&GmD*^5x=%uTHXm&604s{i|)>KS;#`NSoRcE!2~d+8xqV7*YBvL+x7x@$kTZF_~P1&WBbD(Z|Jg@uk$P-{D6U% z6Z_uXd68#aKe3yZK&qf+>eBt?4i_Cw%|m8xQgKVH#G#ICs6+>BRvsZP68RL~X;2dz zIpc31oolMN#oQpltA%2FP>>f$>i%Wz3+?Z(Y67#ql@NLf$M02L=Z@C3jFyEb9wY+I z4jpQcjPr^&m_=+fw=FAv>k+8_Zp9gkO{{Vu_Q|4SXdsdH`S0=7R6XX4;qR-}A9z9l zE%lcT_B-^4Izm80s)Sp}FE(6{kJ~cO2&6PJGvQz_dZaB0-S7TL+2wNC>}p2d2?{@> zklU(Xm*tNHqw!eY%-@H(FZ;Q%qq||=JMqo1y)N6>HZphMZqrt5cYXfyBV}{$97I`BR5^cM6YY6K3iC|v}`ZW8&^TI;S?%f;n$wUhUD7=ws#Hh>9k6$Bj z8XmCnJ!?*CuYhk~w0JRlRu7u%`0d*lUA{7ZGCsVU;W92$Zm@KrL;OI!+4s?o8nw{n z^;q1-o@#eo3{Yk*{9NXA`plWvdM!fDyx4rQ-)Z~-r*gctFJZsL-%Yvj=-6mGCs(sp zk1x2j_zf1Y=D-`Z@MY>^jz$W}b;+Bdwbs$P9fC7&pR-HFu%q3YHG_~@Y5JQk&G}4O z4b#9F!mz!$jIDYjU6_jFZ{cIBW`}zzyEs5si&B!Hg>}I??xY%RyrOmPG#8i1vGuv- zpUS&fTY*z8dDE$X|8v$)TD5A$V2?LEsxn{ai2g z-qya;>>g7B*3WOJb2#pw&2)TxWwSo*QejiV+O0ENQy%8TfdBG13}t;GBTDPfo$F71 z;mH&i*Q5%7w^*m)l)ae;YdZN01&|KI9e=d3pm*p928wNUed#5B2z)>FOx_-6!|43^9&wbjtj`79J&RUMrddvO$U?p2dDJn zaY!ar3CYI#(YlNn4dtzH#KCv!WJYRwdgSDcFtC_Br|Fv$)60(ZyMF!p6+VAHi|7$) zv#q@jRj$mtjU6ZgYa$X&Obe>-PmN~3Aw^NTKv!@?@uVEZ zJOh(>FZzk9D-s{AMdE#e8Eo$5BNEz?BTl;m13j6kW;eD5+>sF)WY&@TFzk_!$j1}k zGP@P|)v1eSE~Xzf^!ohd{Hms0h`fvxz60{~BNNBr)Xs;1!ZxJSJNdmCVqR)?3Vf&c z#rZsTDDmCk6P_Z|y>e&V;A4*lF+P^Wb;tbfcFtKJpL#sSN8+z@MFbI=J5aT5hb=jm z5ht@2elzEv%CFeTfuS27+DqiSr8PQ!d2SJq6)ipuyo zKk4B-IF^*uNtDHa818^JsKJ)??~Z_ZL++-Cmh+qSv-E%Aw7EsXmV(TAU(yOL>yD^3 zD6wFqOV+aKJW__V1!{nm2FB5pzq10zSfm*Q_FMh_l^>IItIj+K8f8~l0lv2x+x48& ziOS|3V)QS3Iy~%!MUb@=TkNHZ3a~cZ{o{+p{k*OfiK9!)3trdP(rSAav20vi+{xa{ z?p!=QXA9Dcs*0BVmWW|-uSN4CpI`-`G~kC){`&4K0`w4sV;TY}ntPxy!I1})LpH3$ zXJKrwts5G|bX`n_#6*UF4T7%Ud!$(vepRvJ+Ke$DkTG8ZLbeTl>)b^-Ad|_Wxo?l} z-bxYMhUbZ%;HXv1f!K2si}9D(_VD3k#=ukWP3cx!y04S78cV6a{IP4=y+_^p<)mG- zZjpKkXfFz<4MLhQ51>KQmwVQYetON8%hPkwxTBGbU^PEir$f}#`{o~J&FXo3cFg%r z$fwLd9az7|fkE2TlJz6SkQS1ojv{o>ng=^nk2e_gWZntBi~WYZXGp?EtW!porDE9Z zTz|(Qw6#cFYbrQs&Cc|$L@k>fh&5QuqjMQSNG!f4s{zAOOX{mrSyt@c(j79=bq1Kcsr}dV|?bC%fnZ zMBnW~ca;3`vUxAd{6zK#Ob8#_s(2Mey0M+zflChRx-scj;%KV}2CjT{_e^8rL5)x| z8yC0T6YbO{Y!9?OCZYJ?cx{D(qA7IE!s%mOEqVm-puNeB@*TUszbxv$M|lwOz`M$e z?N&|>vwAe2+X@L!6HWyn1m5trUJvTJIRs^VaUxf&>{4+nC%p46)Aj_;jOcocuSFRI z2cqu+S-XA6sHRwRy&Ucx(WgtR?xIIwIBsg$^J}Z$aoB$1w=Q~;7JgIxf_SJqkd z?c{F?C0-kW52D_@j=Hu;heP5UAA40lAb^aZ4L{T{#@+X|5w^Ab;$! zeS5u@ll|9?O1<8`UArM2cH*4(Kp2QyC@~dDJVRR_#-7q#^OqK&ad{~L>nRoYQ21xr zD8Q{tqUO5yC~_GVGO2`A#6IhQst(a;$$edx$9mMtz?(7*A zJ-v`dS0d2#)Jb>|(+&{#%S{au-V_~rC3w7^@4Xen;_Khk+ zVI5fe!_|A>kSgv-Uu7_QH!LEJW9L(YxE0mdinJ%`V$TT>=HACVlgWTGB0Hj8qnw(p zb7e4hc2(cmArPR%|0?cjgD;E@-5FRh=j(cAYzKbtwDIV>?&Z2I>Ky%4{&}{Go%v#B zz$*(jWz9AlnU%{5O1)QvRQdSrm{(&KDRdrgihb{E($ng8 zbA!-+dj0ID$JkeIF{+ZKi5aOpc%OS~-EThe?Q?3*KHSIOw0e?3(IM>|&*SS0FXgR> zetKypq0y-%%Eztl)VJ1UaR(gC-aYr*GU&CjmY@0QF;3Gvscr!Pc;h-D)8g-FV>izV zZ;(5kl969sMh!mjvQtA!4F35C`Be$+{l7A49Xb*q$g?~fsU^w;n+a!j7blq>vurzf z@RNIw4lXhsH!h8_7>2-U4LORQD9d-9D`uLZl+o@tiFS`aGkaZ4+~4UjXWpt>feKl8 zCOpJH@e_4>*;nC{OEG{)o$Ssq0VUa}l3HRJk#*;eAP+2Axlo(YT|TwrV8; zUKljr$pPI!8}2q$*00`e5LM$Xka)DnjUah-Vjr!qUZ<tz@QPeyr+-P7_Yfd&7M-F z=Z@MlZWc(PwYVg85;Cp-_N0keZlq`h`^A^mGnnparD$DE2io!JxYggdnUDQ zby}A5)75Si0V#+ynIDiPU)ai5Wf{g$(DmC`?Z}eb@RB-dk#Ck7Rx-ZQunL*TkB{e* z5@=6l1&(wX-jMKlSp(+D`Qc0%64Y>Ld|cf4oYfUxOgs9pN=J6KbM!B z{RDK6Li1w!ix_=&KUanc7J7{cHDegy)#&M)i=~X+C_G1mxz?aTvddhq^0JbLUYx$e z#I9G&d4mjwG>(eQl{k8kUKDqyp_iE1z7`5r52_-Zi1JYvTE{!r1NMGLV-IbqB0#);#3JeHWGma` zi)&ipU1P|8-`H7$etuhw#8-Zd!r~s{5|KyHM+wh>muD*(_C?SGcw3*1aQdvOcSj3l z?)o#r#b%}3tGz!ZfO5~;vcD8hgxYYy4Z)caanUH=tfl@soF`+%s8M1mBAp`ReP`~S zDn+U!6b6z$C3~|5NUIw&Bx^+L3~C$G-G>T|xuAEL=?M#&^5L}v z9mZ6w+rAMFlXgIh89td7r3^j@TGQ_iz>5QBO)J3Do<4iFfk*`=Py^~tI80662ipr4 zUp18FJh(=#=M#uCqgv}e+o$b*l%&(APctb@Fz^sQ7THv5faNQwsJa48fubt-zjxOd zeV{{=VI6SdRLL)bK=r}XOO$EuA6@(lq##0SB!} zzSTk<>c%9lr_p@1F9k7;Olsg!(?B71Do{#=4y8ghQD__0TE{TAjDPUB<$a`J@d530 zAXtbCBNGT7w7EP7VoeMD8uq=(GQ@6J{WjdwW7c}?kqS6&_%zfNgq$dVIH)(A@5PP!^KKn&6d4VV(wFDQlVrBdz)S!SXH0GRMEPDUDc{p z`yMsWif>`sDtnJ^gpUck+%y3AHxo6K7 zs6^$IF*vD#(AJtU<7J}<$i)t!FWctbK~kiZNP# zLu$#`98$*G4EV*wtx>x5ctHvIgm7PUcPf=MT*$HWBkgOgqkSkqBSGjkB6MvJ4sHO` z#Y2}*29o#+8tU~i!tZnJ`!8LMe+Vwa1(JdaxKXyF4!f43qFkdM3^VGIWN3nfKk48k zqwx^kTBB~Bbs=?M(V?zqCT|1yZwnLvST=+wYsuq_jCj!vdBINA81lOEPRr{9Q!Suz zJDUB*Va9T<&Ncw!;_Pk=6H8|#t2#kcXW478C_x6ueqsBQzqZ#?_q<;(8W^mU8Cr3F zZ8mUa4^(MuzLgG_`V;?gapqileB6|aYX;(rvI%ZU;MA{Q*d%x|uu93j*pR&Pt~D`X z6z*1((|n)dt4{qnQV0*Ozifz2j+i>*g(Xp>Bbkz944FIQfeY1kE-=Xs@PPmoIT4d#?rR^6(m_&_#kZyM% zaOcjdgzrXAc8+KVpq+c*bLa8*XCHtpKe^!}m%)L9A6h@XeWTir2I?dh1!WoNhe-XZ zC|1M&sco5LQ+)Iw zb1{-YOlll_@3wMGWCMHqCyngqjNf6anlPKici%9p4BT3*#PV!8}$k}W+`i$ zJcW2!Pdy}5B(s`%BL;@OaeQ4d!S5Sm9lj7_Nhv9zsdhPcS-HTt&@=v)EI1~onZLOZ z)*;7e0*IIx3y8fBtK$B+?sm5QT~9g?T5JZ3lrdvf=VB(4L$(J7hR5IBnNcXftc-K4 z{js|3huw)WThHOOd{W3V|(;V*3ny!-Qf3Ziy6D3_8eSV(|@O z9a;k^*4Sl5S+NkiW^RRO_|bE1G(42Vrzw57_~s>se`W2TjD3-ig@stb>6Vh2nFnmQ zR8g*oVnzU8X(|DqgppbLqC1{}5}i2XCPbQ(RbMApmTsIpN_@<<+rb|%#8z0&1f`i= zVLG%}3R)6mO|Gz>20S@;45ki=?~?0Cf|6ziyQ`^aqs8%7C{ao~7mdT+SyI54Cb_Ejt$O(!sf2Zg zil?QGcayL1jj4mYnOM}~%<}AvtfCNu&sZGF9YTEO6MN3SeV56n-D$9e9iyPzjaduR z2k8%U@9qNCpqAuoexlkJ^<9rS_f*7voBr1HQF!k2FCvBFu#}Q-LMVVmnSp9|$pea1Fb6$Fr^zhK%At##F}4cdkDfmz0kuR7TB+Fl*0En=Sgp5a0!rMmk3^(c-|$ zHxZ3)Is~X@?91^&`Er$4oA*q3~r^GD0`ybEh8Kp&@)u<7v zMN7G=^C|3!CEXyDU`v7;ndvgajA9k?6rrNR9hAa>CkxvyRS@gi3AXhRtntV{lg^%z zWNwHo=$;;CVsVsOQho~-(eYONPO1PA_VAcSm8)uGJ()Oepa-R#!?#bRbfTTgv&Jtr zU!YzF{}lPQjo0N7m+#um_pgX!>&Z z_icAxL-&o+M|0=3t&dt6oLF!F=|zL50roVW!d6S5M_j%Rdf)a~uVsHk?l+4thHPd| zya5&$6y$L1EzV6EHf`?Qdb(%SO41$ypnDh|I&t+2Lc3{WzWJW&Q1Zmn_SmVbE48mP z6LF^R89q$xsZ+z2S)NLnr>hK*wBG-ra;Jz++}Kx-&ixU4&M`~$-;^;XVB}zn`K(2I zTe5v!XjoX472o;%_UGibMQLEeV()asiN*R8lxY zbq&0X9sDXp0w`8Ds1BmNer6l9;*V4C4)A``Rw@@1Y8BG!h4IgR2`6wo#; zf`VjJk!A+$s-8$SASU4sMmMQx={yfeMQ9Hh=b?X27iJDPOvfLslLi0`>=QkLC!kd? z$>nGhK_Jwr2zoDDzO@7V9FGQ4$SzdmK95?3@R1BD`zbs;u?}KEh>fG0bd7Yj(Y3!# zYRm(^;rGo%vp{46kBM$D;J7c4Ny(^pr+eXRU7zy_0+A0IK#?)@!1nFq-|VHslLz-g zs%6OSgVCRx8w8v`@0O5akdnxW-b`fz5wbtLWcE>7Lc<7im!eCmMYmL9>-t-PGE+S# zoQ0@aBr&*@lyVTORx2cwX z(d*V=b_65jDr(B|k@CYg!In8YJ6C=PW-?KcPxA{*xNB}$OXz%JcnUDt0(>0B?ukgP zG7qc&3>GSfS=PF@wogWcYg{?J&^>KpcF##1 z1SJKGa@R%Ugd?aN!{~b;^7wtgiRzRZRV4mgUGn!qn*V1m;aZ(FQ%|*n<>g!e0vmQ$ zGpxK_P27L;8~-iN2AYl4izaP#yn0OIq#8`eKnSK1E{oe!=a5c5$Yx z*96P)g+a^5+R|Xz@<}k*mGvZdS?dd_5GN& zAn2QShGEmd;hD+n)Pj0wR+FBX8kli_(5!Owml^_?z^+Y&5kPgO&&hL6I18gf4$S#uUhpAHary`U?8Mof>kSvhp`LlCb71@_J2J1gT(Ame}&7w0c z5rKLbYh6NoEKWg_&#zRYaq>W46Z;LK!^&mV;wCh6q7S4n6#3@UmoGiR1ls_hpnGI* z-xZ2WQCm}QivpMiyxHJ2t0RgtEnJH(;~>Zk;U>KNsLaK+e?(|jb1Mx_Z<0ho{u=o2 zQ}#<=Lh2%A2?nR~(!p*Y)MfA)%p7rz77PzBQ)7I*OGt;Oq3%bT!o?}_eAdF+4t=Tb zH{$){5%STI6pCdhoJSo*GNZpfrq0_;{PfTJz-e$^6;svX7_&;#38A98!DmUK;29HC zOa#?Z0VzZ`HyzM)H_lDsq~!eTs)0oiX*~(<(yG!7DP+_0Ge=742Wz+pb#t z0#KD0DV(&hv5JFK_l)2+XN=aHI!d9S3-D$d_9^(K2@|pzbLJmUpQIsHKb$fCpf0Up zO-7=ePW86J)qDjeb)qwnnFz&rrVL~$l4y@maHwFq0wr`AV+rhJQdr^~I@f-uTqAYe ztPG~6Z=GH^9lBZ8FM?x#dcJeq)<>ONaZ2bKt3qJl7wLC%_Nrx6z)mD#^fT4 zhocOv7_iGrJ7srzff5K2AYS&GYvR`Y8{Qhqy4dtN<9hmr<_;hFvm6GCDwIL*I*7R_ z%B#8;e1>Q9zjq-Fl;GBjox65zWVuB{GEd%0nHHn_-#}^lEHuzgC*Ez$cuO}KVF6SS zP!UVUrzItJZ!;e3G1u@I{D1~b>@a8spzhb1h8q4;2C5xDP`yD-%OinwVFf5nQeeAf z9tRLr3syoz=8JC*4F7(rJ-j+h9ungII1_B3dM`ljK_2x~sRHwMi8jPEvB%*P^gB;U zkh|H%f|>Wa-;)GTj6!+~JAfiY01BBxpzx91Ah6va*`im-b7g5ES`^W!j=Eb|_b1xf z`y-8qng@32ysUOA0y(kyW{R6O@eu00?DH$GZGD*N+F1Htp5p~{&Xx9evSw4(b%-8D zT5+I(wjXzG1?-v5$x*l??`#DFotNwVVlV^A)0f8D*47k>Ep)9CU9&JAim4cp$@P}+ z!NkAOs?RgWSedy&l}&|9_{7V1n{lHh`_ouJ{b2W_=w9;d31CDA^X&Pxor>0j@4fh& zD74t1?H$6^>q7plR^7T+h=pApuGA7?ED!zw8JLnp$q5!9PDmQ&c?FoKPC^iBJagvJ z58V#Y%A|oPZ>5KrjwvA|;j8SZz#BcewOgzWk*$QE z&;XynIY`ib_NELqGuv_Fpt1r;_%@2sZyzuItp0Ari&O_OePM8zkz=pZ5PJV;u-dpCuyhZyP-uy$5)oe!N~ zydXM5@eLa`tOmQZ+zIu<+5!%V5>Uwd0pH)>A=Ma*1ZRIg4^k8=P1v~;cRw&~UNguj3yXJ%+TO5rYF$nZ9(+@dNg|;ukiHCbOFB&_lo5VrI`xFfrKH^;3E3_ zJ*Dvp_m_lX&`KSdDR=mOkJUQDHJ)6%mb2C-noQD&_9{4i{!`N;qo%Ws ztd=c1g&CU~K$ZUDexv$5)~+3_Ji;OjWxO@$yXb(}(W1dfP417=_V_YjBzdsBM{rgb zAMM?b8TjELN~K^o-I_}bMt>fb^}Sx5IszyTVnruw9-1mn`Yx0CNG+W@`qhu<+`$r+ z8kfo8);9-zW&O!aCCp3|?&!t;ZIlnslSu`k4M}05`ES&?vA7vt-`BS>T8QiehAdm^ zCrjMO0}hk{pDzCVIvBD;6W)+qDhL@#c42;U^*;Uk3ttV4CAo@F=L!C!X-(#6oSoufljD(-T z-Dhn3@RQktPB|ag?t2OL(#&*Ic1L~vag!QULS#-y6Gyx5M@wliLu45!iTXU&_WIi} z@hp$|yED_%4Q1{<8aZ&~C{n2+%YfmvS^sLJn&#GKOf?db_+RbF3g7=fX7~S3T8$z5Mmo5pm$C$*AF+!Im!zxH3Xhn%DR);=kwYn+84-oAf-X5Ob@G`R}jq9Zz~_1!-YNhM= z`edu_d*4`{rrvr+`OT}0j;TMUQvgzMMBPB-^G@E(P(6L_oDsr7*q+pqE!Tun`rU8F z^AGB?bcS0Rd2K{}_Av0(7c!@kjLvj@JzX(9ZO0@V8~?K^J)7494^H0`*6yF6()Cdt zb`sf;9vgMoX`x*s=)(H>!=5iX!{Bag{dx^E#=BO$zEhL%B+ntkAqoIJ61n-z3q6OD zUKT>VK|VA`5Fzy~1s>&I2x9XzxHB1!LdK)*Z;F(Vq+I~+SJ}MNt~Z&~z{APeIhjwc zu+~^HSpyjS^s?gSv)guW3}P`11&-n%iUqW8onNmAx#C(!(|Fc=9shLGrF}Fthn`y> zVC6JjUVu?{TQMadbjYYP*}Z1drh&>SZSE|8_jD+$aGOCGcEDw&N>Y#CjXdSk@8QFl z;~q`Y(yWF7fO4-=5UZ;L4Z6?|!ama0H792@vC(K>T+;bW7cL&nKb#DR#EgX%b%lMackb-IycO%%gVH^t=JyqO?nONd#t_OY`a5ec3hK5B-DTln6<>7Jo)hQ z9X)->S4@AFJdU?2ZnU7WrgAZiMprC2v!IcBFtfRkRAE~#eoJK6pCZ1Cd6ivnyqOM!i6 zYjiiT8T0wO?c~W@f9zbNcX9GI-v3is;iy8lkWS~rKD#bG_sIH9=ai_6b}5WM&7Sh} z=hYJ~r+s{UK!d!P@B8%r^~6M6tX~d3m^GTsGBghk%a`~5@bP0vZc)mYFJGoSi5}(( zZF#f%>f9jz8L2-;#yrW0JiE5X87sB(k@1nO^;7rUD_Z`_|7MnVx66_FKtl!eVx`;| z9&m5)$=UWL6P#8@uFC0gCihcl&70U{qVF6YlY6dcZ#Bh`>X%(=)UC0>ddd_Z#9^to zZ%-(mwsiICmedfDOZTI4*WPlN{fzkwnsKfF*pYqL&SZk|9}j%iT+~1a@%V+B;-FI9 zDE0BGCIeWr#1g@Y_b%?vwo@p+ef-p>okHQ>?y@qf-fJhSC=??Mq7@3oj=H-1_7Rqt zO)Xfp_{q8D`ss1|K8?Jyb98yctvk+GybtE~%xga?W_5twXT9@fHY*F`->1)b&3Dud z4z(J@ALK;8*BPd!vGV!c<1zpG&HwPzJ$26~s;c~__x~>+>wo_3yvz9u3Ys!e%L&uY zh|3u|JY<4-tB)PxwF+|L_*f>d{4@CoYKN?P@xd%N+TE9r+;F9nd}fpD!(x_2_56Iq z!X{vXs)_j&=N)Hr{m_O$1v^qnjS7ekb57{Le{A7U+hdmIQ(p8lnQ-^QjgvOv;o*M- z{Q9o{;cM{+vn^MC){qPNKY!xN>-&H3+dA8PeTVmUyY=Ujiz2m{|K-H;u`$lKqio*0 zG&#S=l79PbYkn_%HoUmSfVnw6p0qrF{J&rRs5JqBRk-c# s)GfK~BR8oj6hn4QtFBONf8V>$`K5*rBG=vG4-_L!#u^_toVx!118V0c!2kdN literal 0 HcmV?d00001 diff --git a/objects/set_insert_two.png b/objects/set_insert_two.png new file mode 100644 index 0000000000000000000000000000000000000000..6e90dab4f74c3390c1afa02315416dfb8bc75a0e GIT binary patch literal 53960 zcmbTe2Rzno-#>mzo6;^aTF8h(X;>*LWR{hct;j5!mX<_jc9|6tqR2>APAe-Z*&`7l zE9>_@=(?ZZ^ZVb=c>V9!<#k_|bUM%DdmNw7dwq_(it;B`tz=qBp-@(xI(b}~LZQ{B zP-rTaFU5DduCLvX|66P;dFsq^{Lf{%;T`-pqn(txor;LBHAZI@}H`G&Z_)vRS1;=vk<6KG?WtHkw&&njN zl~p?Xs;)-4@ATU1pEPC9CM0p&pXGXPc9Bls`_@*C#Va&U%B>4F6d0M>nHQF9w$4{> z$M-2~?UugKL$=)`f3i6_bFv3*D|?>amyUiorx0KJL^UDh)vK6;?HwIMzkl<7GLZ?1 zt-oMxW#zC-Lpf;jfBc#&&Z;Y7I<F{|L>_&QkkY+@`!fepJlP z&OWK2z`1?Xgf9y_(Cf{AKr9MME-ed-V5iS@}&| zP|$Dx#ZSAFk4Z{S43)4=evkHcnELseQTP(`PU-u4(-T9c>6(nEyQ7FI&WGpu(Vd;8Cy6<%9~Kff|t-}foWV5q%F$n@jYSlJ+bOG|~p=A6vSeVckJ z!#iSwbR=Vys}t1tDay*q%U7?Cv+1H9mzExGyUmtr*&?Q|udkkdVdKoyc+cCx+-Up3 zW{#>8PgRqca&vR1r$?$LrlxFrDp{`IxRL2HDNz6Xtii{}N42u-?kb2)-t-pxb7!-T z!?inimgmmRIyZg$cIxCwy+6Nu4NXkeGc(`!^ILy7eD$(r%goKq{inAdyQTO<(qs6~ z1rM@*g(}imKKY;4|BsVlc`-Fj;^3sta6q~PWGf{9-R z3@hmAJL4nWlq>CAM=FGc%s=})+k~Jj(?r_^QV1a;6*>%h7E;y{Vk$SLYhf|9VOm) z>6X_1{_^kD(Tw=!+2?0UgZLLVsaeV$Z*Mgnbq$U4d$)Y-8!cig)Z1${cTh^HhWE&k zw+asYOV*Q(%{w4qBjxp_ zZ&cwbfBy~J#)pftXJ{^bN<3v~xNB%==)2uvUq3&rLPvX%=QI|~REUYPZr!?rPQQ15 z%et(Rs^ieM1kYQp*!fY(%=qXl*4xTKT+hm;dH>B<;<9?9w%*=n*&loDp4MORlg+xf zLrg4Us)XyFud!MBmw$cOx(oXSjmtlbH=nc2DZ060{r8VgXp_#pF0QTha~>bSLhao` zf1hdpy-!K!1kGx8iA{E{PfSYct%;?x_?mIH_|DzC`874`6ciNf4zq}fi5VIjcZc?b zAF(&Z*?aNg1$CCPk^9WMFJGAOBlwHf*4Fv8wd>P0D?U8jX>DhBrug$~OST6O9>@f0 zCUpm!MC@Z6JkL7b(opNfETbJ4!#9%l@4i^i1ZnB)F7NK^^Sp6`7N<4Jaip7~_4bMv z?XuO6`qeT~Z!a{wsK5@BYgS39H#9QhN~T@3Xrebh@|D*othnVW_NB=D=WKSx40FU3Z-7|Q$1|= zU83mT#?xbDErc&MDe`qBsHg039_w#Isd@9}jn&Mb%VK}N@1!hU&HSM}STOjY^$u26 zR=d7WUKi@0pBG{Z7BpFXV;Mu7QCXm&q2XTVF>?`7(bCFFj(z(cR*BCsJ3Bjvg@;>T zxnkT!4cNuWSsQnHD?U`X<$xc@Y5nRbDP}R3Ees3{e?Cynk)^dz{EY#rhtIe_sk7;OX3K)J^b8FRB)$eAXuy2P^C3up*H8rVcm@{f7 zZNhQ)a}5s<*T^u}$ld2QJ#=E*xIdpn!wc=+FX8tP+OR8Jtg>wLd~uHwD(&)k&)bl!yQ~$TpX0Qe1~T1^-2 z=ZnbA-8?pNvX6{9ioKfN+I!Q`F7+QjbLZYY{khp0l&+5MZq?@6wezpG$Ok`Y_T`mX zm*^6yk?xA#>gW@W3da^Y(0UukCksVg(to>I*56hXMStplY)h#hoY(A;ke6S*^ajn1 ze8t40sQ%;LDjV1<7O`ps))~2NI;q`ld`i398T&7iV1UrhC%sy60yqG za~V;x!3JeV7pt+D9GWB|+hfFN@7#eRtaPZ`Z)PJ|l|KIP;dR;CR z)t+At$>mD7Nbiht7--HZ%evfm&~bPdO3nAtKlI>=gi~={e3SZJQGV+j)=BgH-W;<)JNF?LC{w*Del@b(=O7FJp6&XvuYD>$T^YUu9~9khX#kTA58p@v4yh7mHi-Z#>g} zdmtktqf2y;lH}4G*9r@dOG-+9eq+6pN9{!n%7%l3ga3HlLQ&@Ob|7B3(E{>zt; zwL7I-2M76AHLRCUQtcQRkk50QF>QLY?{N5oU%!40M+DBl>D@*(cA`fwHD}+Ij(&pk z+9kSCiHdfAt*Iqt;ZtRiPgUytIV2$9?4hdT{uwJba#M=j6(2AB@$~<^Er3@3VjHTD zhiXE_>wSWPY3et&cuB8hir;-Nbcsl6Vo4HTboFkAN>^&HU6xBpe#aH&K-GW0L;l%A zN82uI96We%H$ST7g>)ua*)siA5rKilGaVbGPNlul{JFEtsp*IBt-f9p3ybi;v#)t8f^_W$p_j}Q514?DX@sUK&W%jEEI#J&0TS>w&(IUI3yw>X~4j)Mmu zVewjfdQQm6(Oc$Da#(zM#r5gnMjq7|x0ydNF)^La`~X}^(b7X5-r}2_OQ!@)DnFtn zOSXu+&x&|%<}a?V55QUN=;%0RYPuU}B=&UZ0kYrFt<$X9Bz0Vdq?($V(2&E#Tto0H ziVYJ*oyT5Y`Kg&ZGju{;pdb11)01$J3IBxE4>=_d^_hCg*RFEROtq)?>_U-d-V+r zdRy|ur^bF3eEO8}xntw+@V8l60vA6e>I-YNwYA;6c~j(N?{l?eR)B~nn&}rNCMGB! zqonAdV;ef)DS7z=jTu<`MRQ87d3kfQp{M*fM6DtLZwb0Hnqw3+rdaiT z+GAW5;gzqaI3{|fe@j{59)reIqeS(T>-gm(T|v6O42t2*R(m0* zs=5iFLM}ptoOzqkA7@dgi-3w&tXd_NP>+wv`zcYQ00`%Eo_pT#Brsrid2oTx_G6z@ z43<%DGq4$detBNv(g+hXbNRiEJQEWg-Ye+nXj}0Ta*<-;0Kj`MH66tB_?+!12&ig+ zw-u||fwy6b9#xuw7mRQn(?FYi_d@$E>tX2|OILlbPf*KEGg>HM8#*6`XRTmhFroT$ z;j>5{;!#o#6}IfgvK&8gVx;;6TX5LVdtP4bLPGwLZh!8gT@IHER{8HPsH*aQ{CFGF z{tJdSf!(zV;zsYT(r}nuc5!i8PDghvzP9?Q(oXW>(1$Z!rw+8Zj<=Vt;yW+T-7%tEabZeBfL332#;*i!U3l9=`nJ zSF`ir!;lb}st8fD`sW(~=#_Kx@B_YKVdYJkwwYFKi|97<8BPv&l}Ct%0zT=Rn4G|7 z2lRQ22TJgunCl-AyXKMyEFHj=)IJ;>mnrkcR1Y7YH7~R>-%|s4PB(krx${^pSqIc7 zDmofa{9Q%G&uhVMZf?MoJx^@cFLc%N&==WLHa{AY6#zeEjmpt93G@cqmH{}n0;X#I zntpL}_~FY@$8N8tW~|zJ;BiA=fHW75>G$uZs)_371qM9%bMNHkiQ_b~Z{JQ6AXBti z*X5{_(_w6x`&)${l$XopPIhl4Uw_7a%3@t!zI^$vwDd0i05l;bBLk zn<(%UyzDiUV`(p@H*eqC_J7_dA|mqiY{DiV=TFJHd2W=?pFg+$_#t!VjDM+vyu7@F zqvKi@mea8^0scQX^Xqg1Ub+kwZ3a+A&o9Qdeg@=>11&Mob*-pAQA4oHoJqpe)HK%> z^yFB*gus4z9!pbL`Wq8C?f$~(sHH@{r%Ev1t2wOsr* zHa0-A96^;EJ*rJRXRU{)XU1EmXQu`yCMUV3j7&_TYkOtFmh9HR0ZvTh^-DW>=+Ge< z=?EYspz<34r+{RgV?V#DpF5Xk+aurX*u&DLv*+Bob13ClXLe4`+nt?;SAKpenjGn= z?i=03&c1fbmXkp4G*(tt67jVuHeE865uyaJy3frB12XCX!~O1SV7QTgRX(2Q_Yv-= zFHZc#lMph~9Jc%UB_PLnTsg<-a8p#jdR@=x>g;^Pd-7ok4ggx^?qux8b5RD5 zW0ulyp-9-+2%sb}i@Sy8-&m%S=jKXz|Ni~*l`EZ0Yd5Z6A1xFWdn&o1=g8`NHvQ8o zX49?#m;dKp)#M%=mapf~x?@A6%kTKQqvk?-|F^e6volk+(-YRk_Zg$Jdj*AFyDuA82|4 zJs^9S%JX}$CDN=muC1fv2F|F{=#N(xUjx6swzNfCFj~7JKt>7$97q2=s^(1(kLp}k zXFMwE1C}E%U%fK?`6b{X)6n&uAZcG>`@$X6!TlxNXs*Mc+TC>;yrSxFjrcrC%M@ zVvCr|!HQ5}P7aP+SW`u8{7rmXCmkFP0z(*Mg-|k5?0S_^eujpJckJ5-bn6it%MMCK zq!YkOP%63^9U1{aLAD7uje|fR)z#H8ad9@kzbl0ZTV5J=L%DI7o$NUs;*Fk|>M*4L z>4kQJQ1R;3tIs6sgloUOlA>R<@`Y|*C1<3|buTZkQina7uUbDoId-4rNFXW!pfep9 z2x%;noqh_yr0UKDmooXS1tGGb5{$n!>p zn4KO`n4X>{aGjBnkt(VUMQ&okLC2|=9cy<=U46@m2h2~v2`S7X4r{;xQCaivtlfDB zolsOXd@y(Ff$P-RLx9F_Z|%u*J{=;&HQE9!Tx!qU$)Zp+^fIsOy?^IHUNdsO|EsT0 zH-2yriE39?RsxN$S-<`mv?03ext^oLd=;Me?-$nBpAFW-lc&>4sVpj55-xw@%9R74 za=>7>U%e8-M}wwBcme*p)%bumdid~9KpE|8Fu}p0_Cbw0YNieq$pPDiY>0~uFN#V_R|pFW z2l8qtHzmI*2ZZoOh52)BsxIkV5Kc5#G7B^FqeHgFxie%D@fEwMHGI>FfdE7eXeh<4Co9%S5%bF7>PGs2+R%Sbn0QInlI{j{~iIojI zWP3{|$Ej^_unN*bN=k}S#1lIlbI|faEW{hT-gW!-?Sn?hr}ahxVB(eC0_pQ*w5|}XhglbcvCC#B{H{gKd<&`q&({|O=)TqC)I)7~t zn`ecy^VB-;J@cQmFj}!ajtAQe0u_+2{Dlh_u8q%a=*kTPwFBBoZ0fO{95ymix^W$E zzu23t3Wp=pevnms`WJ0!X{lD8TR5BB1kF{*F)0Qms}GoemO%NRgs!_{^=jkMAN3S! z<4YhC%C8>@$?F&yOHpH%)6ga2stxo~l*l5ej6_nobmcfM^y*cLj_c@I z>`}>?KcfNcB_qH?wo_vkC~0@^-#?RaLRz}Ltxf5BJH2-(&P=GN^iiH2E9Z6PAxoA1 zxUzz}`!o4_f^^-K+)&|EFDYJZ$rb(i^|df#S#xu<;T+bECetJf zA3h*W(=j_I=X6G9X68P-?;jWSn4Leb^xep;v9a+!qu?#>v(JCk$np;rZ?)X*c`zIQ z|LQ{hJ(T&pM2)mtz-}X7E+$*|*06Vt05v^5!;NNblFDMkAMT?3j~j5jclVXrvmc#C zu?<0iA6=ePu*M<@8d3e%x#!A4v522<=E4m|KvIB=5v4Jq+ce zqw|!kTD?c>%^C%TD&GS6_WcFKaaAQKU}=9r5<|<{y(}Vy^&F@aFBaPDpsO?7qV=R<85N zYSz~sFJJw)iV+0TX&#+_Nf<<<$-eaVP5j}a4*o&=3+I*kdjjal=e|=ChCc-4+6)kZ z%ECSP?2dBa_>s%j)?7Wo3rDDi<8;IN7#wNHs41>fS5Q5u&WEG?j~_q2hKcDOWNqj_ ze1p9UKdsEsARu}aFued9qcQ6;&+XML??JdOUhIQ{vwM4V^+{#rb=U<>xvrt4Okzhj z*RGpK>#>RDArMvWKp9I*q466Ub#l#YX7Gax)W1>wUfH*A;izqbz-u5#cON|9s}&hC zMNuZd426~2Zz(j4_FbcmX(nJ4f;g%aXt8V7ta%5qeY33sdAqkVIz)1cU5E+N;%tsSwAZ z_EJAMd@#_qz$0UG`9*^R5suRIP4wB95?dy2rI$PS+{f_ZMt=bG`hr5*hX8h<*-GHKYjYtZ!I;6 zf+FotQr!aUtG713^uq@|f}O;!UAx9n@nNW=q_^(b z`W&ZG<&2!sPv>BzrJ~Wq_5$OqLuCS7h;_8Pa)s|zGd@wX>$vup*Otjbrl|CwSLpJ$ z($WN1tXT26v2o*|CvPG2oR=9H#xN2@#+z(o1>$y#L%7750j4hj)18Fp1?wwlK`(9R zQh9#50VUk(^5t0NSQ$!~xO)ViNN{YS|0n4z!pwC0H0s249cP?8O>egWP$ZDde)IC!{ zABk@0n*?lBYBu+6zroiztf92;i7-UpW z=m;o(OK&`xmw3VG0XB%!O3x&;JY4>EzTP$gfpt7QJg6xFk%9sOA4*G)CO1UGF}Jnt zfb6i$X0BoG=FP=jqaa_6dG6wlBiT@%AbBmasSAwk(-ER_wq?p`{{J)j#za)T)96CUm*AHS1_M|Sc) zh%~qlGxV1O7GI#a9>e~Hb)r1ha3LMrGNe3yFT+>P!5Q}hp6#VU_Kg-!PENTUt&t_R zO8&ns8Cl)_S88=rp3lvBS0k90PwC8sbWM%v9fMfd3bNWt&(45fVRtW*0AL}6Jwq2B zT#@Hy+RUK!#>U13OKlskDZmNivV9I--q(=4Y}>(uTR=HM#Cl@wLGFNie>oA% zO6$wP2WLn5$%;zQ#=DH=LcF+4NnFB$3Fo&fkiV_fdX6TpVt4- z7q^s&RStIH7)%cjXMs^eG#H}EGKfzrHgYDf$Z{U%19pvp+yk%*j2@Mp>oBwf0H33y zXC@Jm3KYqj8ef2!hyMOI<>QaRADALE&P)0jh#hqASQI2)jntb<=r$?Bq(m(u=K{tl z{5@#!Hmb=w6*v+^m{xnC)rLbR^B^|XDA%d}!hV#FA}Bvlr=YT&27R*aF5k|@br)<| z#7-)!yu4h%y)wvQ`kQ-y_hiqI>IU|ib9|-N>Y8)kc9;D-lbC!j(cM7X=#SoG5MlxM zSr?Gk)2NJeO)&EWUs<+9z}Tk%9h{Jqygtmd?Z5%mNsZ(NTUeXh#@$}HcWY-mtVP2x z`idgOc-U??WEp^j>a5EbnVFdh|AX&DRC1J&VVsjRZ~~~V&v+xARGXUC#;rm{n*P(5 zOc)c+?4rJ>=wxUjGJ+bhG8>WSATk5A=s468>T}QeMk#s6-CMvS3-Ub?cYy~?z!jzk z-RGh~;86^2LyGbV384~yuqWJp*!93*TN&IT~N96fe&LQz=-~Ib--;Cj@x`=oY-Zyg2%$!fZeh_<$=# z47$F5{{R&yAWhHFq!qTOZ>;*+V#GN_C8`1anSlYcHnsv zlai}6w3J^XBRg@RuA+OVS$sX2vFqw752NDds4+=e?#7cW`T6bTF0O0r$SdL2f;CO*^$pY2lAzm#G6h=1=74@8&b!Vhmm+94_`$`p_Y zl44O&k(8O)Bh zyws9gftU4ng>rHob<^jqQ`>tFI-r^9W056)<60B;T=j8%ouz)jO`b6^yWlgOjudlM z&viNE<17t6*N+@_&kRker?mvvU>s^ zOnN>k$vqLyd@b2KcI@~yHpaou9{bMG#Mqcy{9?K$7Q775w-;Fx0BJC{k&!BK!OK7D zTq2>m#e!?&{qNYhbKe$v;1~V#L+-js*em#1sp(A%!GSdje##bE7wVoKMOx~Rb^BsS z%^V134d%_Uez0%>u7kI>^f7cd2)92j^WinIimXg7a~I(~ye}w# z6G#Wz!XcXydHC{5><=w%Z5p&b+SarxF_f2C(vhGLjlft~1LgX{1#V ziVj1YxhfJ`-jOT)yRDib3KX@pL}E2<@OGi%Qa(V?0KXwRGBp><#{SIL7m-(^R^?3( z)4{tj#CD|m4uQs*H@!*e)cuiHh{X$rID@r;o+1Fcmiy-i4`huftzwO6=~Z}YN|k~e z=gUi!1Me$Mi(Id9-Aig4AcbaI1AU=d1MmmIOyV-RNmMKVT(hqkNu?(6^0a|BUZ$ix z!F!^Pp(iSV?VwZmTL4W0BDJC*Lm7pA_89%(m3gBtcuFb&I$|<+G?R*P7K2sLF<{Y9 zH8Q5qz#d}H4)v#1DW_jJ8z&bmX=U|txbf-J-LWfZ?>u-wl2F%kUju{GrW(mY!aELs z5PAxX3Ox%8?bg}3-!EN<`SM+uv~yh;aZ(n%Y?+a1OIS+7EX&5{TsNv&&jq%%m7F&- z`tOq@8+3xCn!B78hnG#o#m2U^w!TC0Aw&%;LLPw7rKU&xxf6>%h<1=34AE5@b*{HQ zA;=d>$f3(WHbAaI6=eEgacdL5PNI+jSON7Q)U^&Ign;R}f})^OZUD?e)(O0cW2CP( zUg62*B<;7G)YR0_(?~zrvu72UqSmKJ;o%k73H~$S%kVN=X9rhpgXQt-msOm6_`PaV zLu@`?^_P?!9R;Ad;h%E~nn`0%rbLofHQ?YNi)jK_D1_F4W0MAk1v5jXS;e^%p8g2S zGDmmaBBh$Vt|;c)u>tItgCqZ|uhGX@GNZ%qAr%s)O27{cNy_I;TTVpR6f5<6?G8gE zKbowQ<6o7emFWw%ZeV02h1AsPfnJh(gf>_iGzyKX8eOn!6ap(LlfWKSeI}Et2qWkR zROO*Lb4>!jz}|k1kMqCcfD6=R&Z3tpQ9J{!yZ75$VS)+!KR?9h2l_y2W^xnl+Bo>b zh1ZwRZ8>1R1)&$nqC~0wN6?5mgCh)96JQydo}ONFm4?Ke&~|nw@7%EiXqA}XuzqG3d zq}Xk;Yjf9SRn@@ZG(1-Ll5m0LHS{{rFwDPYoo(b46VsVI#LIghW{eHwex?KFC*c@0 z<~R$ZZs_4(L8hI?`b!Zgcm&lH`o?5;V0idxI9e!OVWQ5PAeH-Z@GD44E&{!TF(=d_ z$pjS$z_$Z=O(2p=P;Sy4FI*l-i$ha~+JP5^zf05#+2Q>QLg)5~MWD^vnKm9^pS3Zk z)*FT9Wo7$+{tQ@3|E{=L+A$;O^=o0+cFG_=Fc`5w zRUpRxeVi>09joBnP4p$_L1U54J@otxH#z3g(o6BY;rtwEnSwH`g+c-7jp{_gD5YXJ zk%%c6n3>&$35Aeq@s}@}j=ISWf=E`N3m})A+8(h04d(Rmjzy>X(-P0Ut~C7WJ~!3k zGPPv!;>WeU;MN@5wn;QLzp*wTAnE%AnjFXY2}hV+hzGb#<;;wI^>_d*coZ)3lfkbz z!e#Foo}cY|!m!^BG6@~?v52y>cJPe0LqUc@@)3Rp^cw|ZV-AvZ0Nt*uJF}YkAS~vc z+}!s7bFpX6wlc~rsGh9CMkGH}Gz4g3^Zn!Yu2Fzgv*BMIQ&mFUNtd`5Yym$>?dJ6p z@u0~@>G|)scon-$K?fBG_SQ+}PfPiyBj=S2$Th^A^85ZNX)B2d+0Exz97l|=U%!5} z$vF`?7N+pITvudt-T=FE2R#3nKE}er5-^UM?%!hr;bRyrOW(}w6b#9LnWV%-R;R{) zl6?|~gtZ}4@M>q(8J^SBWQug3J%okf_zD%kGd+DjwiURR57eTy2-`wE#-ikxl-$O{ z;hsWaj;=OE0N4aY=;@i~l5Bj${YTGdp*&y{e{tV0Fi;vM3KTK&DczxP`1RcX2ZWxd zruWwLjUsUQ2pMvk%%D~1XbIFR$I~?shqWi!k(m* z&wH%gX!`LnO}s)RiGsR7Hvm3rcAs-4(Ewr@AQqY=LR(f^dMYzF%97ih=I#&})m4>pl*H*JtW#4-)K&~B}6FGQrcW+BW^x@TPqwc~nd@9O8j`O1m+b#!(lJ2oYIVf}f z8;TCvn;cKC?mWN*eE?a@v)1B%L6>0!gX0lj(dVs?R0IeZakB_Q9UouT3ZzZVCB8c% zMQCT-#Q8vtB^s0w7`hk{M{{(li0B2bK~nz|QuHBdsHGwk_A)g!%6)FO|LbdS*w~;y z4iH*VjoQIUf$W~VTgJEfOhfd<>Z02Cmj>}M?z-N?mKy&lBf4_-e$mYMAx8RJJ6fjf z@|Gpht3S$4#6l5hiEU#`d7+bYPdYjuQZ5COJAy#?R+(-MUo+UcE>>6mBN~D2|@4+oT81jdgc9BZ2k- z+-DIx6F&%U0bzj{=;(f;zwiI!(!4XMvDu=1)bM#oMfRPKLw;2I^wYczQy6Z zE_smYJbsCpg~jn_dIK4b04gc?`ZW|1e-!d1D^|4Sj5l{cDkqj66y{Ve`Gw;*RL9j2 z#{%p>Wut{F55 z&(>DG*^$V($JM5C#rJ_E0mSEK2HmN)uR$LtV1Rya$`pivp~fVFM?t(m@U<<1#&W%` zEBxMd=eGgheFaLu>u)uZ@)z4Nm< zClsS3-AAVOLjWL#Do!#2FLf`pLm^V48N7pG4US*{AdX4`$l!%0cI*~?8zy18ZnL?) ztEysvUsE%Ec)tGMT%+*B#)7CAbmos)V_q&>kB`@vjW3R`fZpma^^RVX6(0LueS=lh z>5;iDUb(&SF0~Ko#n#?lvs49Ct;yCK4EOe%EOed1yr4v-*~O*jR!Jo{1dYfYH!GV8 z*Hjm=eyuUzT%s#yShmP( zYHB(vobdNW@DP{*B7GDVs!Nn*;isvcnsJ;bL2W<7k%9=<1)T$ll2UzEg}wi+BPAE| zg7ePXw?|0ovL@!#@%h1lv&|~&VhaljZopk-43NQpF1U@c2EJZ>*|hEaeC^ zE4EXgI#e6%TU_T+3mt#H8`xK>16>m7uSMbe$np@`Ft!7f7(G-P$Sr$jFO zLpliY_;+8TPx%6>P0xhz%}cMUfgJqL(GOgz(wrWVNfAv@0@nH8PqL$MUBD%fw|T7I z;aSpxF!(!?HWGD)1pP`WL;Qd9+ca{1t?>2npz~Tt=OG`jqC*1C^FunAX2LoN zSHk&1yH#tJJ$X_hNfmX2)hN{4n*sTfcbIlUlz0=b`mc9GoN|vOP+lpI_FvqDFay;Y z3w`j&5!o$h<^V%lltMqHeg2}E3Tr=^#Yht9M;#Y*E}{fuZ_4C=Vr9?GPJt``0>HN!Y!-EcKFNLNsRXj7kZQ!B`LxXr zX2Pi`F%=TCqaW(5?HlDNc|YT>D|NOe&&Xi{`t`qW@&D@i9t}oMROebY-hxGhaM8@y zd)$M9#2pIa*Hz8HgWC$33Y;+BJV7&^n>zprB*G0R(G2f}2_m#8A1QVk3LypB9Wl9Z za26>77m_rQ(HxLcR6`$}4xk#GXAOK_$Sq4A3_@p^8qD*qHr>U=b?VSDVN6GX72S!B zjxL=g!C&YTM5x<&;=#uhgA;@$qA`Imd!Di#-^)JP3>fe@FTb62YwXZ#UJYON|M(}? z&*(e|&AP{`37PKal#r+B62w+RAbt0sl(aP9@m&}d89-cg;Oyun=yQC^x8NIN(b2DM z5WzxvrxKzXMticO`fUfA4y|Sr1KPBZ6AKLqxd+AsZi6oJsC?WFJ~7eXp)|nKAU-9G z9NKL#rjW&7ig6%{j@zWs^vujDIXOcZ7VyXQE?)G68_8$HTWOEYGx^bVa1O9WHoE!| zGo1%ZGK2E}n$}0W068Cq(u(|bw7I9JX92N%z9O_qCdiO4n?^F@vV9mTDnx3r4>@i&(3T)9S^>fk``l=|C;F4o&^=hSw%GsZ1Aw*W&Do6M z@+Ig&ux~LPr^z_trkV69#+v$76=weJNVCKQxqiDUcx`v2_fq}s>jCdmO zwYU|kDH*Q>vLfU*&uvCAp`K{?*uP|)!L~|NEynS#@53^_g>lo4#518UK7Upx4gv-y zv1xfVUoH2NCL;@54%zG?p<>IN(M|hE<>wW2 z&=;tGHxAoxpeC4XYY-7Y(&-jTHK=bvK|yqO*+S!rl8DXHiinQh3Gl23TygNwA+E22 zf`TN0N?0`1q%#>LQ$~W$7*q%jo1~&+l_4{#o@Ts?f{6knJgx7ePF=$}Q0mj%W}HZ- z6om~-&a0an27(;;^cHXvBr`ZGL*R~k zZ8}e8sx825kxw$Ca%#{q9Vfej(1rozp@~c3_W4u*a3IYg1fz@I6>2;q)wY z4LHR^W&C+-Hf@rIGl0`&2wQ{0))Lm%{tI;^oljJ-Oz-}GR51R3R4}X+DEl$|_%pN= zYy~4cG@`r0=*6}pv0Sum{+B5m=HkI5AuB*{mfM7EYOLu4*(JdEem{#u?FH3p(4%NnRI|Gh|mX;O;#!h!aa;|b^U13qt z5RxDyQ*C56DctOE17;HV0Y8b>YU&QDlr}d zq;dbyoT8zjp;lo?Lj)oiuU$)az^V}v88@wta#@uRUN-Zw$$cv_9B^dh_=Iz8y6z1h zk(H6zAs|2m<1{dA1Z@LaNc@ECk3D-TI`=L5TPhz=0VCVb&$2m>vwW(XJYY2)dh_L4 z|19B89?oj#`XrOS9{ypTu5Y28{3+{s`muz|gU{7XzSSRop3eQ?@DGVS1AFf5Sib0b z;^LFTv-w4nYmY985^!>V;VEl-u&1etg;g>_BmoSW+%f*09=<{^-%89==OMBK)2>iTtETU>@xA zTYG+zghpE^*4z6F=W`LU9$^?$iA9P}fcJ_&Oa&@OR=|U9b2l0avOO%AWsr&0$56{K=G*~40(wTtAOpV_JI~mRFzW52dXI*osZkNeXSb8N13Qfz=ijbx zP}ltXKcy2`Lf$RAqXuiAlw;TDHV+(X>dW^KLfZQJWVN)IK?+oTNh}p`u@2c~2*Mcj zc6g<^2NP^$wi5k}*k}mKdqOma4o}icq~^g&#{++3Kd6&6^c8~;P#OG;`_4 z6uGG>NM|q8(qzZ!wxLAf^Y+VVEbNts%Q`YC-U8U0wXZF8;ekD8mW4V;4{*$-^=9wX z_#mflt_yU++qnJ#!~95x$=Wk;-pHryQb-jHmNWMLyHxL$4`synIikSA<0R!qX;UDg z8EqKLdyL*kA~D4IL6%_|1-=RVGDnP%)-=f`)PszmMLeCwnM9^dmtnfZf@pKI$i_UH2je+->fGMisQ(VXzpqt@5P=*?60$rk zY6HGs;J%VU2y`qP;9x+=0_<}}$mD>eMU|DSZ{$C2T901BirYKN1#WEVctah)K8t=hf&-)wW7OGN(c zL;oXe6-Z^qC7Q2HkHTiW+8NtLgL3-RMSSO~XHfL+ZQ2v^%w|42jf-zC2$*qgPDz!y zw3Cya-N^P-VV}>VN6V)NdwA!Cv*D#?c3nG`tlU8Hb#6W0Otv~60>+*iwKptuypdK-J13trjHZV}8s(=4Fo{kv4=nUmUni@7iuW#i z$}ZJzeGMo@X%tkhx)K3Q#~A$yNi44EwX@_^l`l&`3r^HbzXwEu>HaDh$^sjYb(#YW z7(x~|>$dB9$a$T| z9MbO}^`1b7+$Fa9qAnZ%KaJ%-Js*B**>gN%DlN*rW)euVF}H-3)!t`=erq+n(A;OR zj|;N}&Y2w_K=jp6b+gU?<~3!T^Zy>Q|L(INf6;}j2>`j_B;&dL#S~gK-`8aZhK8Pt z#gUnc{7iUCZcOqFsUKPPQVE1Lqva}T4VkX-p6MQhF;mA zHowYuHd7yZy#V3IEX;Rc378bPqYIGi*YI#VDs!(6@zx0Ycn26p#R89WSq@C67(xkJN$ANmf}XU=|5T+m>mt0!vc zkPx9FU_}}@?j9<)ORj^_h>LE51#~(0<4z)6;owzj*pBhSD9i>!wX}jTAU4r@!_EK! znLte1W0D>o**i46)hvf8MD9dAhgLxQ7!qzayn4Lr^Olxm?yq7Xz{lq*ruYm6xKfah zEC&avfa~c$0<(+sLRHn$XdzJ%5h8S<$YOxxKA0_K&4vw#4i{8ZtU7t=jQ?(>>##9` ziz>`Sos$a|M$1W>0_{9P#PK~iKNwIu&=xS;$LD8xV89d>-d)e7lYNkZO{@@6E@)L` zG>b%78q+xO&0Uzj!c8oS7!ijkT?}IS0j9mxl`EA4XVQ4NxJncGVqV;43T!G0I^4zv?tsA%63v6c?DnUZvnxbFe8wNg3#t2!%}#xLs6qTy z(9BX^zm7L7^@TIHTB3L6WabOK{OgFt-iMxt`{792DtD5HZV@czdKk)6H1s4`G$|N) z0FE;HG$PZy{*E%O<&_U$z!F`oN>vp+kR5x zUu|)|NA}ehr(%T5mZ|KEtkYp0vC&u2f})w0VN`pBgoxQ2%uD(Wq=*og6FBbRvXf zd0!#}hIF?76VX880ibImkkbz8i96X+a23ozOJ0>fmx_Oz0lDD{2~DciDAGq`a(>Ao0OA+mVNM|5WYPd9Equ#n_w;kFi{YHAk*C+KAa?~ z7p^&zy0&Nu<&90(N{DF%kcNpe10|3Is-c-dIeZ5aQ4@b=`9r$cY>8vTFBf}B`?XyZ z%sS~^YDmD%GZ)6Yk$;-eRjJEll9j1_*2aS~SvCrL1jS$b+v+wf_Yi()DeqJNXWPv+ znO;Tid&pEiu2sSPgB-Y1XOTc|2}H<^v`gvrV6yrTS;wzjwL zK@b5$V7Gzw2*;t2#0N=>;_u=vFcqCQ@FZoyR(hLrj(~*<^Q1u~1jUWVA&?lhDnPE0 zt4kpXyB!a|wBNf0#EcBm01X6iN2$F5R0AWPyS?ELT`-J4 zifu#-rTYy3O`eoa1exTE7 zJRwV9^%ny!h;ZNf5J)1j3ldx#__Q8j&HVUv#fS`!co3f1V_erm6@f|WkURV5BB+^0 zivAK{N$`rbOia&(q7ZX>s`%vkI*>KxCz4Cj1jvmlaD!4Hm899k^13~YI$v;$`JfdA zMiiuMNNN(p%)&@0ZOi2R2@{tH0u-bV?GA^p;};Uz0F#FVda7`8@XB&8=%c3$pK^oEqp=gizpg?TKix+ddD|o{D-=8m zCchNW)%|V5!@_V2kT|Ro5Wu<2E(Sy*P?N}nA{Y+>#YDQmpsvy_Wm*{qMSwf;*@+Ii zNIwvHZnpcFObUc4)8&j{F_C5VZt*uDn*>%VwF6jcxbny#xuRxUW&C;cX>s2a<8ubdpQgRC@x)~`Lpz1xK;-Fxpo^PALek<4O{7#Ug`gwkH1Q4FLayx zY~m4+y~#aVvDDBmnPBI1yrqSCCvGEk( z5)HXzigX?K*-1_gzf+~X08G3(*;}qcxIx${m0nzpT)lxPiXyAHW{)%#1*6A$0{3X%8}% zr^X$#5KYEG+KC&}3Kwp_BbU^q<>mQkv2|C5d;0m+%0^5Y;R7nD>NJ8QUNVmrG% zKsZY$qr~^djT?GAOqyqX(-$Dy}0LifyHz$F+f`^KrV|1Xlkh@>; z4pfiipRUq+F; zFcx=$Nn5g0o-96`|GGpCKXN{jH20I+2+@MB%~`B{IK1UC@>0}7(mA+zF3&F9X-d=@ z6c-YVM0tvJpPRM&QMUqn1?9+FKHdOXe_pLOJ}4-$YTLxbSRwjj|KIlXlnqHeeDI)R zqWV4}D8ZtwnNci-O+gZwrECu-|NOxyRi?2v1n7D@!NB3pR1lc8JL^T7jo!AP8bO{!H93P16zD0ntCKLdEQ zvxE>PMr;Wo<3GSv9rywH(;fe}rv35Ee zT3QJPm7Y(#4tz;Z5MbK5AJb$+z`>16z^Z>|RY5fi@odNmN2b`!sYie)e=sI%AXq~W zN2CG6qn#e3N0)COzQ-$^MbzChXEqQC2x|tAcpFWVelVpIx2(#?cK{N8{`z&KvvfVi z;<(gaFyp8pwg%N0!CO*giBK1Ih+K|ChJgqlgRBcZ7gs!Nz)%Fa3P|8M$+$8ykyk8lA5dYGK?rUqTy}ENZ27HCahNV9wjHPzNdGZ_Kb=1!XiT+v z?(WF@ox)SU*2(IUq*{hH32rETE24^AQh;}Wd2(E+hU^nbWg~S?qLVlWFxt38cYz1? zVB?86{F3NBieNHH_Mz?bjDN#rep0q?vE0O)1AoAEW#l4F92eXyOh)E~F4QfDqzoP) zgKRL~Q9HI1BC01C2bPx}n*cvQ4JWatkXVWEfsqV=mKC-;pahiwlf@E+c)5PP?-EF>FGtNkf??+ne!K~U^*dq@A*Y&Bxc=G>9~0c)kF{?2RTwt zj@|aJ-pobrTmtYXnKoRLLN1yk!UEC)PkxT}m^gp#n-#9l3!=AyUi;mM`Qy%rV?WLI!9i8jh{`*NoFh)n8Z$ zdJoALnlWklh%~!`mys=pTgZ$Y6jtJKqWr64YzOm5G59HDERivw< z9hT!hhhKU)J;tBZccYY{urKj-{*7zKlIRtH*drUCUiWXvL94gMu0^QiwrWBwIs=hX zkSqhlJB{-efI-kzDsgh>G5kVJ!BHOpXXW;06LFBhfv>F)-U*HlM2^H2%=(WP(#g%W zD7VOi;u0nj%eacVO>PJS+zBvdwK;imIf}B`rhLMLNjF7G29iHXLs(;2CANI&jiZy! zMgqZbu2^9r>VqSYqy`M6(26viAB-UKbYUy-q4@3d4EFaggdF?`qrWwZZmJ;Oq_UFx zJ%JoZtg>KE#edJaK;)x}&FKQ_Ag3a=OAk9K7E%SKtoB|0aRy%G8z3avK4NT@GNn1B2qjagC{vNhJcKe9nWFxmmA!w@vw!dN{{R2?INs;j$FuEJ z_kCaA>sr@Z=XtJk*~dm!RdFNkQ8#Vq??u?nAiD`SCXT_UDMIfrSx)`)^aukceq#oZ(W;roIq^k!=I#7#5pG zpdk?Kfy0@?V$+$>bMn6I={=6%ZYZcFZH&(O5x*cQG2At;K9-MhY5m5uolQ^BN??|d z{%&!uN|#^k%*@KNK0KvgaiW0ucXyPxgXa_YYRsO2mpCRbi<0$7j~zi&@1?qp3RyZC z^MKyhmaJHjmeiud^yAj^ZK-9HR`Zba(>#`Px2}Hn;yA(qEM&h$>Rqm1uij&tiumix zo*oihh^^Y=qkMaQA9Em2`W7hk0?VT>XDt8rQHMB&;`Pz1SGm-Y(g2QS%mm|;y;PMT zvveztAmFe#@QULq#GZ7ragn?*gfcqm2zn`ophOBskXT75M0W9lpQD+uAlP_=PDS(W z%V|t{jplK8aXik8oht@t)I(-|UJ_Nvkh# z0)vXPFh0j!_goV95-iJI>YE^@h2oKd3Lcm;cd+P`TCsY7Xf39t)34aB9TLurI;aRgYNDN`wj*~gOc^en_E+2rOtPvBZNS{~*ZnSxqn2kTcx0EHUb$FP?behHrEK*Y{tCQTl9Y*RMQ(xE-%Z z5g_o#v)tfjED1U*sO!gckAHty{Xt6keA=j&IO69YLGpiXoY!1bVN}~u2w7CRP7376lEwtZ z)1nNGh@ zE@Sa;6Z{+z@HJA!JE&ja(FseJU;Dl1iWJkD)k$;mK6rPJ`mN&3a2;~)iBxBz79-EF z$j}`I03n=^0DH~2f4K5| z%^;y;fm=Eo8n&k8O$r)bDTU++qAEy(8F&f!$X;wO}1M}~=5h+o1Toqpfwmscd9g*y@?$IGl1eap0@jj4BC#kbW`czVdj8*ji|#!bU3pBqSC~aWO*|u2tiOFjvmLrN zIj=*xnrjrC?c2lKSsN?d?<`*(xaY*jtIIh70)UcNUmfR#((oz!-NFl@@Uu~`GLE_y zy~>LB`M-&*NDR3~>vd{8CgQigeQ(cyn&o@Z<>1SgFO?Rh&viZ+w$lze5)u3}g4{&4 z!<}6ZlM5XoYZv|(I63HPzeJ5QJ~f0{=Y(hL4Po9f?ex(7iz@qDl_li4?U+k?j%%}r zZFyW;N+Uh_S?5!mJ31r=?sYD0^>UqZ_t_LT$2SUF>)&#u-N7G5rcD^H~*g$=a+ZI|70}v5APqD-{zJo2?z7skQfpvo1O#k6R*1R(_}}~ z@jvd(^FbL+68NqU;BQL12SAMyA|eMqUu^s6lZ6IP$cZ3{4NCIiq&A?>|~k-1zoA% zOe5^^i@)Z(ls)`tp*9r|ovcOFv7{VKqtPR;BmDWYJ+Z{AD_$8TbX1DU5B4+*Z%1U6 zG!O!w8l0MgFj1PIGBWCbyg_|Yg7cZAp5?~85!i`@%z2Bz6HozSi?pNrv^@*I62)@? zgJizfUzR4IqAH-qyx5v&!)GCoQ$=qKz^&E4e^Gw4$!aytlI+Sc}11|Bw8bI55y-o5Fy4hR#R=i!a)j+@3sc%RF2St9?SU3N_vKyC{G_$WY*pu%S14}T2XjaQV|XP10!zC++K3GmVt zk0C<8w=Z5~Q_;wfG_HdySuOq&O{_?W$g^Si&(9nq0w9GmCGS9TXDC|*JO!{wWXkVE z1!xKFt<*O^{aPhkgE1<|razRM=8`y)P@XI`bLv%Xnxon&5m8JcZ7y{`x`_p5Ghf z4CReSNoXatMjG*r{0*%JJAmy=Nu3`?xSzrwL|wvt%aEZp9f$d#*3V-5euW12`0`$h zD3^Kb)(*CnNHS@_`jX!B*)V>i0AFbBxrGSXX7L5^{Vk~zxpGIR7D`|2{TZ`STVkfu?rFpXe1QQ!Heb8a*nhHSF;6*tnrC>9~d&a<)II&bfC z%yqbn>miDd0U?GzdW4j-!@z-I+@ifG?Ut!eVZRYAd%}a2-a3>k8UDhrWJ)7ZPUC~O zF~7%2yyUnUYi)nwHE2LY8L*s+j`cd31O>zf{VMjWK*OnOfBwE`z|gaG5vJtK=F z!*Z$$Xwq#pDk6VrqXu0|q9&KYZVHN~Od`F5=jq`GJWkhBsX69P`W!hKjcP*_62xxl zo#A{u5}1j}B6I6YyAeVLvpro%>z6Ci4a8$_im&>9)*4`mEQa z&re0(8~ugLVhdb^0Y(lfIWRTdK*$AZOt{gY5BZb7)ZVUc(|yv8sqiq19t;#726{sp ze!*cBV7ATKwWN3oUfgi7Uj-Q5%xIo}< z&0$6vIgF|i&)nw#d=~&%g=6P{J$n0g3n@1<*+_7OG5`)loD_KH2afC_TpNo-LDWi= zO4WB9hW%WUrS|pc%V`FLZ=mJ}a_{uEi>Sf3sXmBtQmJrV`1$qS-kRfW|Ny1Y>XhR@afC7r{ zN^(Td49E&K@MmvUjfc?k=!+wqH|iHTc}_F@=k)8_ciXo)WdjkCC4UR@Yvgr+qP^j2 zQd#Pp1GM)zUq!_>hnEm|u;S%JIMrD^iP_oKo@!hnn=xGQR9hO))k42UXz?o^;9=Cf{tHhq)Dl2sVds%G1UlH?uILOCzN&Xhu z*m9sAHh^S}+-9)c+T4v20`dL}qZ@297Gf|ck(5%jR}rSZP#DCpD?*nS;f4-6=cHlJ zV?Zn;?WXoQ=}OnGwqjA$WO@#`@N`HT=kicGy`d7sNQQQlM!XtrbLUw#g;?G30>!{6 zEIEA~G|5U(N54eF630wMcfv*>4Vkb&C36XCA_VOvu&vzS)Y`iJ3VAw0)(uE#vOW0X zst2E~a}PB+e3P53>fSq)b8GqCg!}f9BR)(7hy`Se>Ua1jf&loo+zA;L3a^}NMcci9 zw|J^|V04!oOC32TWn?HA5o_BY+2?w1d!e82&966;)btLVotDt?ztt`UjW757HC`Ax zb!=zp32oZByE}d*vyMLrJ9_kJ(zm^~@itY}^ViPf01JF5f8{eHXOPxc%g+ovP#`9r z7%Ic{21@`GHe~VxG9l@{b82>&u9Tj%z%l*N`S(3}b1&rPj%r&3975y6cyGPhG9HU6 zS$pg0w6y#mS}CVa-9X^7Ece4Sw8ud<-6%Ep4p8Zn3FLBPezSenu|gq|ul3$FYUi%@ zj0JT6(7mbl}*5Hfn?9z=@oP}numt8fxVT39@RW!=xY0@GYgsK#hRob<6dynx#TAr45{nYmhIK~5ls zvU0?Evl8c@*Hy;>y!~MJGvX{LJcR4Bi?6#`Y$?D7?F#s~&e!5ri1Btjy8kQ#ES?Oz`_P2a9hDjFv- zFcAw^BxExPnqoxEFMINHJ_3;!PO$+uBr`4$!Oj7>AX^oDqV}cAMZb3L%;VoyvODVU z-l1Nu1@DLQS;Z-k!zvb1LUQ8%(#6n_Vn1#%-43G72BTNFSO56zj3E-e_0Jf4JKk_! zx5>v3CiyQ#J9)gg(_c@v($(fbW8|Xskh|>VUO!4wK-Q2=vpcZm4AdMhH9aFSzn zSD>dO8;zV?WfWxRb2+Pp2je8im70!;-2nW=%RqFdl(==u-1Sf3;vW?(xI(VQp{j?+ ze!A#)tVs0Dc}+Fyv}h69{Mn2q7IiE#OysCU_jF_;?EO5DJn1CCXO#5#JfdOf23O=p zur5R4sD%dKmiDf2b52=Qd5(p?{~v=UZ*a99wBpm5l*ewSf3<4&4we$Fc5LQPyUGoe%HmTigfSI@)RMYEx_|u~`U>)X zQNT!*0$7`L%D(1vK4~RC%P8r~ltJiCxayUVHcVWm)eK{NhJr~k$3o)9xc%ewn)>ru zbAgKt7v7WBBk**YzQBG!q!UbsO>16?dr3kv_Lja#e5rcFDa7tf?Ol_ZmNhbOGqT&# z$LaORO{GI#x}$oZEElOI5dT~n1&H4D9}x%cOws-MBXRb?uF?HsZj|(N3kV!rdbH!w z#MMTv^?rNairR(}0@!1s&W?+ZtydlB!A+xi#SgUm>q)MY&#onI7sdTrZ=wuwA!q*I|4 zebW>V87xcl@|t_xcQ=-%)c@4wsTck1*Nn!01=4?Z0nrEZ*AA6U_SfDkQ~UQ`nE#(G zMo$K7qs8Ki|A`+~wLF+~O2IFDaFBZ*HuVeBuS98h=QFt<%084gkq1RBxu6L#Tjbx#*S>LY zPEE3J6x8=wq)r$PW@ly9r!xwDCNeDA(>|>CC@$C={H$W|KRPS^ zf*lu43Z_ph(%S!<{cxvGYMbcp{VUokXAW`vTMHnO*Q4UIUP9J4y6!2NWLVfX=~JTV z6|8><%|n477*Q2fx*sAzv=&ToSb@Wv)WRc1WGlVEi4QhjSISv*;^=-gDUpF`#mot< zXfMdK=l8)5-&S~(y`ahOXLMh5;r|Wmv|IQ);!_z51!^IP#Dgyt{igmaM0ZS3zZQJs zLw}etw95(ro-K02qUb{>I{kMCbR1lQ(%~QjQ&%q4)WYYo%>P7Oxdmp83BK5xP9Yo)e!Y9R&6BgG zY&{y{pFVzko<0~haea8(SvbDTenG0Zou?>+Kos~fMn)%; zg5Qv*)W<~wA3mc!@T!g<-I`H|MKNfn-2b&1Gfl(fWinF1y*6Qpg@ zT}^Bc<5oUXAvz(1OssugwgdBxl+a-y;M~)wfj2v#K85v#n1&AnoM*-cd+99 z`36YiS5unmyjaP9u*U1DY?PZfFH5hKatsw0=Tg!?Sw8e8trw)X0~03NFf?>~{wwi3 zcxFiG>xb=mK+=Wh@YME9jo?EGTbB=uj|i$OY3=Twc7j}%&4b5*X-IYj(l(?K?L~$ZS&p@|!Ho2}EDQHp z{-_rL(nZ=2ve|5lE0UAHyX(9SSfI@qE|vpQ(_D9Umg6t$FP^3**S3ymh{spm?drqe z+E6vrH?KP9hy;%3u2(209H15&yCQvgw2~zWcZ4fKR2RX}IIX;HKx|T0Ru+KX`|3IG z&eRD_EgHOfRlpGy<+?+ZhnZMS2;12DQ2di_MYga0Y`uBWl6mbD>Wt8tG~ec!ODij@ zhb}hllFzurW6-FEsHtxI2joF8Q|E6^m}^3m7tkt5%FU0v$_Hs$lP zEsrR0ZZow9fW>B#c-`i8SvIy!o^D7;h|i*;wvIl91a$eN>9=pIvI~miJl4JJZE9+I zkW0DfXgUyuw7!o{SBSuJ81qRYe`{o`qOQIf-Q08}4^#oW@|V+$C=yPHtrMYY0%k>>+eTnA!qf}=V{!jjV>g`7!zu=pG-L`|wsm#OPoavaW4(zL3^ zL_hk;!&cX3p|ohDI6?%pconnIW2kwC+!jQ*4gr^>IUfmLQqDDik2=jX2A(4lb_lXS zS$0!*aGSPmHzEAnm^pI=qh;JHN`vwvw293PFxo*!~`+Zqaps~)r(4HOdvuJ3a_M_B4fUT+V&gpcu z3%WISSq7(8K7x{_aXTcDb@vT&d-?8NGcPYM3X1dj`AH8FkNw)+Ej#~H8WRCJwAe&f z`Jvv4DIOoXa2k=L#p?zGEVPz+kbMsX1qU}6KYsjs_cRwro8Vxxj$Bnkl5_JO##be3 zCw$8ePb<~jTpqVdKZh^ydk0ZjX0EcZusHYPgUw3iHRhd%W>(xBKGl(qWg~n21(!z^ zglnb7a)J4HUf0S9|IeSz$Lo}vgpX`fliX^po2x93rluq|TU)ay zYW}Qd7SN4tB7e^75W4JdKCymY#Ad!EU+=xK=F!TZ!-w=Pso`t+Gru}`%i|BZRkK`E z!k+F>ww&%;>r3UkpLQbqAlH!0;YRl*gENWp(-F?P>W2?fb-b9Hn}PmAR2On0NdLyi zHCParVN`f`=ke}7!xFVyXNKFWY@TVQZ+RjAMq!~{BOb6-S#r^%GI!nX;|uL)CZ0S$ z)7jBMuoj^~Kq(#phD`U(yVI?`U6s)+-}CqGwG;Oz@Uev3bCV;RdJNnX-nI9_30wc( zKmTz<1>G|1o2{Aw=%+=Y=g=wj(Dy|WQ5&+7xN zG0LJ9=VXe}=9_gKl|U*^E`8DT_jeEc&}hv>L_@k=oa+2@lQel*vcCUwR;Ner-WR}1 zUPHZn3tu_G*8BtJ99oqZ~@N)Ep%fj{>8b z^Q0)Yd1x=EtX80%mwba~R8*8tbzorN>T54dQJ_TzwNX*o_r%lXz~RL54@%%suG%1aCM zNTr)Xm}PThPA+U(bF8)0M$AbyUyDz9LJzzt#rd10`+Y@4aq7sQFE>|ZcS*-4rQG5@ z3=GyFQ;x9K!7Vs8zkL1r^%z9Z?{vz0l6g%u*yu@Q=)IF%G5p98WqPG#LhrVqp!KMp zACuAY?V0?`fI$UJ7*r!*i;@<{;4<`aPa)TO^y!l+-2rF^6mkzrvqzSy^!#ub(Hkk~ zD&y>}g$I`cV#%$aJ0teM$TrSBsIIa^JA`aDoPc=|S09pBg@SxYMsfFGj0&EMGV=$R zn?jRl>QNnJTn4B&03WWXi(u;TLE195!g~sP;Xx&Z(|7>sZTAz2Lxq4RUhf zD01S@)Z9A8)$bap<`lcWcON)m#i8R9rh3mT7;HOUgjVgC{DD{FPFnat`>xX)M*7om z{ZOF%CHKvemml>$7TfgUltqsB&-^RM5%F%e8a0+pt)tj`ZA50F%i8Rxv1y~HI&R8* zQh#&g8yI{Df&IshsnBwl3EwG-EEE0KPf;8)(`dxPh23CY>u@OmrVZumSOR45KoOAD z;Z3TxZ97BygqZOlxTMsls3b5oNCy;TKKxe9jb#iUZ+uGhlsT>DnNKd=mi<(xXy{*| z{~!16-*I!)}|IWpPRT&r39R zQ2!glj)meev)!a*E-N#Q|>f-A-+{-oYT3^$X!{mOC9m@3va4{*` zNqy-FbYD=efLA2US*S)kAwBD15IX{fN!3xrz+wUcO}?MH;Cf+UHp0Lo zl)!BLg1AMn8PhS<#WDvbZ*h@P&k!Y=S(wjMkD{u%s%k@OmiZ6Qw5M7RlG>0G9h0_uv(YOb|^YtWTOU9r2Z;{1gR>yCblaZ&23sTpal z!@Fxn)gBqf?1MKJm2KD)(oT$sdCfR&GYr{b6vdJ`}Hy<~&kQR5H^Ua;`8>bVe|j#=rc++rarKR|H#K0xsee${1x=ov-GA9-A%eri(#~@#v16#Zw@iGJWjbDRBC$vY1S^sxtUWo`}nA&*j|oJ{gDe) zJrT+)H#gUjs6PjrSU%O(UZsbdEa>-O+#eJuo3B!Rg{t5vFM<l^}xR z{}=8H;?7ze+a^8d(7XTm)`z~<&H4G(FjjVx7LotNoo;ZMid%6Vm7&6f5^@Qk6dhIP zn5%fD?X9VnUgIffogM>O{rdIiB3h!j6}#W>F9uf&-78TCp}=UzuV-Re zTKi*jnzAy(y*G6J7ycOAd$`(&EX-~4LL2L$@@36;p%ZEC9c^!{m3 zpFrPa)}-ak6g-dO>+zd6en2))!R~y@Bs}Hh#O3!~^y$v7y|I>q8rH2X6%Oc**gBAm zivggos=?4s9=Eb~Rg^t{_~82WBUc@>2vb&0mrH4V+&b8MO1Brsj32Z!MI)nq6$rYyU?eax2`B{xJAJUx96BlJX^4y+!G#i36u?!eZ$GG-6n1ApEgnRw=rSkzTMqy))Co_ZR)C# z_Z_nkG2}s*GFaWN>#KwDM%mX%&2?P6CN%N#`eBh9JFhz2GI@yZjrfx-d-UkBdP=v1 zkB2S{_RlTWeK)#PE%)~ApJlRZN?K8^-Mux24IB2eG`lown?)qsJUQRfZ9yf-%uvR5 z^k9nM<*aTbq<`lMj*38r)$??D_0tub!?7mK+IMp-SG5WwaU)M-hSh~ds9ep zXU&;&;N(eFKma_)m`Z2od3xqy1dHhuxieKMX(k|9m98!NC>>4HU0i&4Y8DS075@r_yTpIbo~Gm(!yH5rLtT)F zbYapvy_;6*#eKw{mC13<3=9lV2ua&+ZLl>*#MDyQfj( z#(K&3Z{Ael?MoB4G%$U2w}0>()NWshY?;5Ss)?E1;f*$lw;sOkrLaiZ(S5wlpb72f zRn`lD)3)F2n-esJ7B?|j zZIKeY{GR(#r9(U8!4HFyt?pMvu4u>POA{+A|M2>{TmC)bjY{~wYm}nT)%1DRRhHhm zrD}Q}aO44dXu zMTfB&GXS5o=)KA8PtH!Hr>mRWdb5s0Fb$>)EMjirCrcXwEJruUh4 zZXq3$FYli^F>?jGQ!02-pU1edn=kJfG&%MfYw`YD#k^sI0>}1#aBu@@0>Ar z?nXi3Cu>5(aupq#RQ~O^f(6qSZP||^!1|fXqD9Scalv~*xA<9cv5j*z!lc#V;iTl9 z@eoo2nySC|+6KJMXNH9g^hhe2XF7R{(arXw=9OD#TRIlGt_@9f1jGB-!7s~CBf{!v zR_}!}e~OydQxK(_&F68I`<%&Jrav_{gQfZ%4q#IEXg!aDTSEO}$9V5$xvpJs+L^D< zcMT7*n>v#ou|@hldnOH;X%O|}uHDpmrguN&SDbCL+fZxWw)%k#H|JbsT0Vca=%!K7 zFYAZapd`Nn&oyjp=j++DwhoQ=}&)vG004>EAuu=WdcbZ?D-%JmK;2}$+x=wr&>KQs{U4Z_T)mJTY{{T za*1UC3e6?=!|MM*9iY;tjSR_p6*YG~1qdngd8TGa3u57w$L$KTAIhs)rY;*zB}eGm zLYdCgdDr{x!ea^A%%WdgKwN05bk-gPZh-=G| zc|W14)axPL+6%3S8y3Il^*MqwD4129ELBQLKrPZWilD$fIc7CKuuNUvH(1aq*nB^Ofj;YLvVaTHcwSIm~24GF;@5yn z+ji}0Y|vm&)!$lxM0+JgkDfi_K85E=^$!Grg_*D@3h)$pPJ;wEQS3+PI}9hzVQa0hkLwbub#TyZfcbSxUs}> z@B;&ec1CK>?^0npDAtiOuz?(Kdg3+q-Zclwfy$WiUE{cnV=iGtiYNCgAQOn z=8mx;Gh24prIs?~@UgWvZgcM51|#{t^3@;m*eJX#lZClB!1^z6$bJ@ybY9Ep=BH z2bZCzV;o5es2a(9PcCefCpDoC3Q!a$7uv3s_IB({ zWWuwUn~){^NlH|B<%vw3;4^Ok@6^)OZA8{G@>aIYoRKC^@fd7b9lwc&zf#+}5ym;x2X4vqHCE_)23MZ8wr!JuZ7X0%}LI2MFZhT?N|LZ!~rr z{ngQ=iINh0N!~gnFtt`cvF=cQO?S@^FA&$zXJc9@IIHJWGtk9=wr=aP{C!>7L(;uW z72h~^LeZ>O2(%mZ4DofTy{d2>4>{n_1|PZicJFSYv2{ennxtRZ-n3 za#p&B#%yrNobxq!uZvwppswTS;)iu1WlSm_YR*0A;h!}MquA0RU~dNXvsAg1jyd0x zC;jo`$I$P^$4Se!U7EER&%#ulNe9xphq`!;vz%Z%Zrt@*uO3^<-{uxi(5wy!3mctm zHN<0Z!}aNEp9_`^oHo%d@uTj8FuRpwSH~H>t~Ji1tq){YM49JbU}X2gyLMk6%@%s* zdsf7gwJpp;d>&3P%KWx3G-h;1f5qI;iuYaOnmHB!7?Nxi^<8TLk+IL)_!Q&%*CXvc zTkSn#UA0cdX79!Hr)3iyq7Em5A*{`W@H2mEljwcyFXkoHaG@Y{W^UET5~7}ZIQ1zW z7H#_z*VFpnBF+9=EdTKo2vzDNSYP(31fPvXC6^;u?;*NDuJ@I!M+xvliykNyj~!>3 z9=HWh>V66(y#P)Y35CB864xB~%EdSVCu>}oGi#PGPGJ3+?7xG@D_V5u(xpCprMT`( z#jt-|!z|UpD{;1LYC`^c%vBEW3b!F^6^k_4_~J`ecqOlqb*u{A9CUJtMpF|Bs zZ4N~nR_WOC?My534+yA303$yUODvoRvcS!hRaNbaT~TUg;{7O2-+)6hX|Zh2nKQ;D z3ss2=LNCYbCU44At+O>depG;3AW$NnM~e}c5s2t{nMoey^BEK<4})b@H8tCm`2=cS z?Z8J*n^&=0@T4P0ad=Znv7CWavW)iHoBg9%3(+!zNW@h1bh9BMOD1ZXGNozClr3D( zfYk*9Y%|kjvI*u(3Q`zpJfgMvPYNsX>?QS*0z9bn%uIdDMJ-!wqDQJe0-i1uVFa;8 z44YcU-(Ou7oTZDPjLl@IJq!%()CaK52g)9 zXwS&12BfAhU%isF76ru=qlEJ#JGa1~sRLG##J3U7&N|rUFrzEi?S>ize*;IQ!9PB> zoYgbrN#A3nfY8iOPr4NZj)b^f2dnXAm!n)od%S z+1)qN9t7e>5pSQ`<8hoHUj+BG>sO+i{bJr*v)7W(^Zfk|ojoHZX~n*-ZWmvCI1kn^ zb7pO~t?HC9(|y+%$hE|HA(PH69;1#Ia|Kdy1N`zNgc1KN5__Mvq(`t8b_i>U=d3q& znX3g&JYe7!!~@5F#y=$F5_?sYdDE$rzf_Y=_uy7*Iyu7On3wi|rO%b;lAc&X{i+sd{t=4bh#4BG` ztn|z75NiC^W`zENep~V%#8yih*OSSly<(g9vN->>1+u{!uNmR9~vibC{fq5hJezOC}-*8R~9w=gtwp zyiQtLwU|Aj(Pi|`an4i!0jUFy=y}NmA|b8p^}ShR89W2b;0Qypv+t6Q++XV{vOD$b z*Oq3uEQDC&tgZh97Dag86gJZS`24mAbqj9ZNZkah+R^_J2$#8~rA?XxXGLRcbh(im znF;BDLXqZK5tm=-YXJ8~4ARomYs>~r=h$J~yMbnzb4(cKiN#N|PL^trs$DFzgyI7O z)bpCnf$CvsC{ywu?8vFoWhM$#?i1bsHf5)C0vhGNKejR-(~)(^k!FCxG9B8C_3gnBGmJ}TkcO%b z^6bs?jQleDjbKlh5Q8)%I^XCb>U;%2uM)+kV&C$NxH2*;Nt@Z2%A3qYMu46QJ&24j zYDB$8=aI1xNQ#|&AS#itA#wCvs+&QYTXF0h?SA6bKr z!jH6i*M0JFC2XFB3zhVg4<atjiR|oxkJ})|b=Xv>O#7R^fXwhU2Id6AAXS>hwiS03> zY6_1kN-Sx!pj$>HTbY#{gd>TGRx6gD!c(04A{ zo;;81XIE9bd@k{eG?p7YBxDn4oQkhO+KR6&K%h$8pRt>7GggL^jm`5W>UcRM?pSTn z2Dgry>ItG{?=@>`txno>i1TQ9a@o3DV^fLP@)_7}Yp%V>pfX}B3itrR^T6x#R5`B1 zc}0%lbd9YW>NReS#8zQwXsF0J;}>k+S+TFc=;c!UIe!<~pNWYAIk0U>C?w@PG#lDg zi{yH%#==vIRo+q{RhWtq5DcGq&HDAjf^tJcLSze?j~+c?O3y|LHtII>&OXc2Ff*ya z`Evh2?#lwAnIWr{6r~^d}~nmF+?GM+-iASwS|a>nT&7FhuT;(fOa+B(w0 zb`Jj_1;GRQ_H@p*OS6)6uYCeErN`-PmMX%jEHr{NXM013TI^*T-NtSdMRMacCi~p~ zyiUTSQs}T$LW9X2CwKfDtex+qI+WW1yOHtOebv~S4NG$9iSLq>REN*{EjFpNtRw@P zL9cbenA;u$H7GyiY4O;T#LVf3>U2NP8KL}lG z?A0IR*iAIs>3(vS$9uzFh?`@3Z=fB$q&Au(e!yIb-H zpG{6s8M+nOcoeY&^`V5|TO+Kt{N{(QGIh^Dk3SJkJR&=gDXHvRI>gP3@QjQ{ zF*o1%`U+3|Iel{8t=R>w3?&4c-E6>sQ>&(QWAA}B zC|p(s&dK{kGS9@1CS2Nl8E^4x$Ara0*YKNs!uM6{jT3yk!kdp%|4uB!2qlT ztXPCy#c91G`5?l|x7s@REogoi9ps!Ti@^&dV3PqpL1L5vJKxvEzNYpF0J{eIkRS0z))N3{LPr<8ofn$!PLj7qZg`4tDtI%$ z%8yawG+}I^Ktx(COdkvDNSAdX%mlvXIKus+keCdstGFH!-yeDewPGJGRys3R zlc+oaUlz4AgQO|e;QAJGI#t!x87@rXgND?ND0HQ#!hFn_EW)Y)-hhoGod==0 zKF>#mpcG&3%+9C6CAH(;Be#&IL5fxyZyF15kDfsW0+Q&Y`nO?pljirXSa=!2@7KLuW%ac19&AZc2rX+AkHm$b@C{78~|$_ zsbovEYU34fEU8k*kZwvxa}yqf&R__RS`HnJ*2;xt>Vnoj?U;7<}}$>Hu{{>TEaqZx>1 zEtTN8kgTmqOCq1PXrJNOYK&#f)1Lc_;uh$KjP|AlL7axU{Jy+AuvIL{0W@c#Q>mFY zjDE+r{Q%p<(V!M|Y>S9q9C3t-fd_h0o{j;{BNBkH=M_;!duC{_GRcIEkIVnIYdh%J zBRI{tkAa=t?y#OhWzs_)<8@z(1MsZJ#l?|*R~KaUpD^N}j|U#1Pe{Nd6Xk&B0et9Q zTWQ;BRPgall(_=Bmu33*x7^vIR!9GhD;FR86M{tE3OddHR+^GPi=>6Wzgm z&0F<$`0iI~8q%#`IFbUqrf%K``$ zS@Pi6=1tlTbnn5Sj5V0AJA#tBRPN}}sZ$*uxhVj8&>lmx(gfsxqUo zJ%}0;y()i~!)j#IM!+HTI+(FG+V}c#TViNB{2p_LB92*cy=#y}eR;R4I{xI2Gt?+@ zf@CDs7}t)WeQ-yjzP5k!Y5_K=#p)Uq_rTOIS>6iMZ{Lptk2Y=v14ac zYN~Y)wDS5+*0W3Q1|FQv%5$wB@42N}f*{Afq#8*q*RHMS6$A`rcZV$6QvfKnVE5SO zErxFFfBnkUbrTZ4k31Bi^vN)#`5*defISE7TCTtew)$ z?q21D$-V|bdv$FK?N^tM?J@6PaOK@sOtMv2TPfs*0nzA9aMU7Z5F5Y=>yk54VNE!XO*BH>=F`tdg+y@2)$IjDFw7)k! z@z|j5`R+CcwH73pPQ86bz{2pkAV$sIsh z3MVc#5RA)ckGJ6B=yV^S>{FyQcre=2MaOz)e!K1+dUAR1+E&r4%!bcwq1YF6pw73^ zE1La?8v8h65YUNsw{8o!1CcI>X|`Z!WeX?NbP5x%{lk|7Xo=-ywbcm{a;E*!rDsk5aq5)$lXP|DiqlUOV4DR{r)aTW#93Yi(KKTJ3vZ ztNQ-7pr@hX!X#bT*kkHI)kk_nPv*|H$B&<#`ip|@Hl3on5 zU|@dJdf# zxyjCRXvazY`agPG;yvJoje{7v09*~FrEAxeK@$M2 zF^1(ILm!LUv2U3btwKUWNkQri)YzJ( z6j(3uuo-jga8?&;PhpWX_0wWGfFOIX*1igT zY2?*N)v@o7cZ$g9HlM1d*Z#JAY;lAoXW#O;#)AuPUUSv`&CTFYNYE95Zye_p*%?JX z^(%_e>3-U0?61i3YQbwG^{}XA*3my_tWoT|gOuzDwf#KSdwX~6-aTQYgYFG`gMTM5 zf%fZ*jFdd1_VugWzWQ#(fZvVw&0jq~hr~~zfK+UE!fg43cIvxkdd)Sp{P=lK&YimP zx?HN3>ZPW;0zWq>7#>nSB6Cz^KE#e?iTeRVmz>QS{!xy)4i?4#sfA>9QtqEM9E|DSg+{kKF+4ezU^7GYQA zcuGNa``-!oYpQOfN}u}Q40`kPw)h(D)u;WU3AR)92cf?Ym`W}^P@`F^Y4Kfcg7@3g zrKOf&G|zk&x6w>#nK5(g^Jb}Av8svs%#xBcJN56cMge#M z-5$8k^+&m{w$nJkW`7J={Ql#|3#bOO-2(dl7G#0qV~bEG0|uxAqJ6=+c>0VP=iP4H zd_s;TP;obhw2PO@i_k086TLBY36izjk8-8Kx-MPX92$ds<~+K)F%6~^xrkkC zw*(G|a~&QsKWR8Yb5*b2z0K(9FHKwF81EPL^X}W&4RnofZA=#bxTHkTBdDo9Ff;Wy z?U~hcF7I4};iL1wxAzY;R~^@RSnPz=gIY%KzjopC^+n%Q{4V4NEqMAiuc7ZV^`W6b zre680W5`HW^`1%#+obgd-qeaRAO-zQ!Ur)ESkDZbaLPSl6o&h%=4p2;=x{FuD?YUM z@2M*UJ?HvCG*_cNsZDvAIpAH|S`r{;#5W-#Q?04?m~N7sOO^g)U1J6C@^vOb_+_PW zF^~Lw;8B}TT@Qw}^WU>=i!L_~N%`ZCwI5}~w%|>oK0x&DdGK351ur_%Y{&#O@#m=DQ4DTC zl`2#P_BTR|gOAKuu%HPtLQxhK6}#Cic*X3yrt;br-Zl~L%LTzQaWBiL z86Otu36PNF;%I@+V1x|3Jp;%_TGCdjtpNCKf|)kHsO``G_@ur%?!?y89d^;)Z(Cx8 zAfvsg(!bE+T}vT`dz2z#URKjbD`rICIgaS1(O%m7<-Uq5x|NLs)Fxyw`cqCSgI;ae zzkddQp$h=XM4yJDOSyB@siF|~b24F7E-OwP?yhCVqE!ICtSfUCP&>Gfo=)muVx~jGxN;J&HPV?#E^W zJGcp-=icu1zYx#NHp>50(-xi_=-eNc0n1JWdI#x~+U^RMM0YSvdUN51_a1MDl*Qu4Pi$#tu=kqYv<^8 zd#H+35Ms`h%>#`sl$+>Czs)>h;J3F`^>Ijh=@mpNI*W@;Aw5thsQcOl z^ON&bu19Q+xsaXRfXp-tNo`)r(m4pcIzmu!>1Hs_;Lw*HUEm$0)0z%rfiXBl;`Kr) zQr}TYFc`sZgC|c|hJ%dEERtq#zV-cIy(XMy(7Q}X79o|sd~w%@CV&FxU4iosr)h|8 zmjm`R{|>(rXFl~vA?4GTF7EfyF!7-q)=hv zyFi?fdDu%v{Za_pkO(>eFsaqIul>{D;mNMcOgx8%=XdTz-g2m2``&6N!s*qltuX%f zvJ=WIJ%?3GE9Y*kysLOyxz50wX7KM!*Mf%T&cH4Dlx}0YjMaN?kI(v1}h91NtCD8!Dowf2BzN`&RN)udB z1+(Dc*t;Ny%7B)~^==&=A#HpO$kgO^p`*5e0+#$dmTt&p`A=zRm*F7o`Y&rpIb-9n z(CRQ9gfhNv#Q>m=RniG6ef0?bg-1ulDf766hJ)Q&17om{=*)jc=M!5IYF@|ZHM9C* z+Q9?BAM}=A03?~4KCH@W_UtaCzqJC}j|)1r{Bt)P8aLv^(V<(nE%DErcSZc-C%G^f z8OFQoD5Bjj8@GIzkvw&V`B?M1tE=yyRq=kHIr_T$YuBRVUW@Pl26xZCgmxL{Ifzh* zHv0?it8A6r`p%mTW8#cCyW;?Y0X$^hB+dITk~THbr8s~Awe#%C&j^xE^tzttID)Ro z&;z%cyY25a)$CVM-YEiiKY5370M4EYg=pV}hmtqUtpYMLY{?P>1Wd%Z&9F2eq1qZ- z@{;G-si>$-@JOjQ?o(w$%wokbb$|5dKSFlAJ0frjTaAOLMLIii;zT_2t#yJ|r5;?X zyzjNa%aoK9Y5T=Oa}7R}62Acw1!W?EV7oWiKW-x#MLW7Cc{sGIrz0VWpLz!Mzts=J z|ATCq5VXLwL`7n}cPp6E;(PtyV(8EUxQ|SLWFq=W1wwG=*N=^&HrspwCT866zHhW#Im`{8x?xIrLi4e2cpy+;W58O}-hK zHa7joiy@&whZ2o1aTIZ+rm0gH3^`h)y%(=s$>iXPA3L5=>VQCU@3BW0GXV(c85`I3 z)QU-yLdO`d7!mYMU>w4wctIlxl{u_UY&Dx8GeEWmeu>gRfN-RDLl|o!^pi*nXy&62 zBNKM8De+Rif;+8XpYTTq;{3X7vH|`HG3z)Z&SK<9E02)Wteo83c}MJvb`}DoQ&VP4 za9Cw3s2W+=i`%%_-WDS&kgeN%dRl}At^B@|U2R$Nf#!O@w!OStwP{12%PaVNN8dzD zO`n&PT#}v|X_19v|*%Ys3V&L~`EJkM2f)?l6UdCJT zy|V$D>98T4$^;pn^zd-ZQ6}R)fBW_-Qg)RDXUFz&opz*_=RaQ%uI0y&M;f1&-d8$g zJ#O4NoObV0qqv0kRO?luF^AA}xNPa)S%0_gon3n2Zb|!OV>+NU0-FQli+HrlOD!RgeWCm)M2I>66f>T+0i+gp+fr-;rQ{;XF$u(|FVE9Q4}wePy|;~Mwv zU7qjnaBS|@0k7A(&a5;^`z=Ma<)9T&&6)-1D>bu|{(V54``&u9EY@?sM^>n-JvNs!QA5Ts$!5wFNL~3e(n5gbwKGS(z z@$sX6-*?>DDesOZw7Hu+FSx0uvHnPe(}l>eI+yG=Iw8Q^+xGj)cViEGz64Lid!GqK zm%SK;o%KhzyM=|()S17k*^cSI`|6donlBdjOWF}1yf>kxLUFU_-Q$~66Pl)%4Nu&W zlN1^n>iQdTw%`x;J2aOsS=?6X@#4Nl%~pnG6knWl*kQ_V z3dMVG=g@lZ;@1M&`3^npZrMh`|J*kY```WdMXUo;T84}setbdh@i*HIpY+{Qeqy|@ zYs~__JAK5JsbTj9e(`D=@AV@tA))Z~>w}DDXyrG2RM7*A7MsjEkKAN7v`LdDHV@QS zk@jwPxHd`oMMkq;WpBQ$8=l}5^<`C+UR!V56USXD*R1r4jz6kf*>aN^odxkGS2ON@ z@1eP}h2L-z=AC{<{N7(r?+Fv_*y!^4m-- zcG6NUpJQJBu-!Kuz1Ev`0xrEIcGy&UeWfibz&TV+Q#0Yy;V)VAb9JuwyK&s0mJhd# zefe;2)v$+mE4+TJct5_q+R2!AZ%c2T?bh_=r5}splEyNc;mC*g$L;mIWb`jwF=3o`#ON;A z?H(AXJ;A#E_wJQ#TID9Wet4AKZ_1YcXKS9m+6vrl3cQyvo|&21s_xGYD{Jekz%2`x z%EFu8z02$E>3IQcH+U_-d}~+fYG6hVetUOS7jTvnBmrzvZPM{x8KN}-yl0{pxZ*um z4HT-mwf2{v_18_ZUjKUWe6LCS{@pGu&AAt{vG(M-Bfx`r6P_!^+sK6j!$T#{_)C?Y zm6eqVa34X=k;hWf(wBj&B2<6}y4NBS7tis+Id3|FJM6*^0QUtKh2Kk>I$N~=_*LM# z_lY|8->eEAGywO(tpj$JRs)Bcmhk+z53E;8fS2va+E#@Cn<*2XoQHVT)ZQL+cGpYb z7R8;*nOP=2wlLyxzB#+(u)(T5?pIT1Ez>!D2{>(N0&F9k_<3S?_4$=gV!muId$E0f z{N&6??sMCpKmYptUjNtc&;7Nx>0f$16Ic~-wI2qCPUGzM?WySp3uR_5lYBA1b;+H# z>E8tV6#m<6x;__tHlBkj@U+#euUhKbLY*tV{tbKk;vR6SnNM@3kDjIc z)+?(;ZpLlP)t=~~G1t#~(xHbRCb6@ezI)n8M|ab^$&Wq4EY<+`AatEgR1pe{&YoRX z@;)Fxe?71=+V$kE>ou=^cUP=mAMRb;y)EbNB4Ek_t|!d`mdY1z^O#3&Edu4i@YlcB zzPfd3DR9kaZ-2k|oZhIHq37OfOZBc=y3_Tx{hf8d-Fj0>Dn*VhT7B%x_wTQP)fVuk z-A$mAWpjb&KYmY&xT1Ev(8ShuEpW~lSmQ>VJ$v>Ra3kB+^3}^s%*>w2NyhjH{9m-~ zPUO}*t1r}CDO&IJ=fdmm`~L&)*HjvRpK@po`~N>d@+G;~)a!r5Uab<{wf6+qt@o$9 zb*grr|5U9n((fAHdvkB~cHrp3QsAz4;DuKHzPkOv3uAsNR&e{IQRsB_a${7M8b#`Te!U;I9 zzY@6q!Pnn^`koh6A0M>>w|B)}N`3bHd8&llN&e-_gEWEh6{@m2tXi^dVTQ@7YuCa` zOG`h7ZDj~+={r03*8kV>uU_wuyZ%G`|AZ$QzBK`OQJqj1FsGy|}Za&wlT3z1A8%)rJKRo9Bbd;see)yYSPXURv>c^L<%Y zwQg?P`$WA!f9V|m(|YEs7cO)JZgEtK{8BXERsTCqO7uuv+vM+x{(C~dI}uiDvsVD* z9GfGHxT#8~01xlG)9It8e0y8!?J`g4LK*j;w>8~%Mo!Y226Da7-aBa*PuEU!(ccd8 ziR#7Exng_oq>-8r|XB}$yKUmvkFu1#mt38ij0q0JE)W+4+N zkT7f6r}Nrvi4v;u%kHd6F^b#>N>Yoa|HesiCF#dqW(9dyF6kmF{YyTQ#rES4IkD9s NX-`)_mvv4FO#l!d3X}i< literal 0 HcmV?d00001 From 5b77e7ff4cfefe3c627ac08d438bd0a08904dfc4 Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Tue, 4 Jun 2019 19:24:45 +0800 Subject: [PATCH 05/17] Add files --- objects/python_set.md | 0 objects/set-object.md | 1 - 2 files changed, 1 deletion(-) delete mode 100644 objects/python_set.md diff --git a/objects/python_set.md b/objects/python_set.md deleted file mode 100644 index e69de29..0000000 diff --git a/objects/set-object.md b/objects/set-object.md index cb084cc..e69de29 100644 --- a/objects/set-object.md +++ b/objects/set-object.md @@ -1 +0,0 @@ -# Python Set 对象 From f17d15196cc5c3ad9e7cc5d4335d8cc976ab0abe Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Tue, 4 Jun 2019 19:26:51 +0800 Subject: [PATCH 06/17] Add set object --- objects/set-object.md | 576 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 576 insertions(+) diff --git a/objects/set-object.md b/objects/set-object.md index e69de29..2dc79a5 100644 --- a/objects/set-object.md +++ b/objects/set-object.md @@ -0,0 +1,576 @@ +#### python集合 + +set是无序且不重复的集合,是可变的,通常用来从列表中删除重复项以及计算数学运算,如交集、并集、差分和对称差分等集合操作。set 支持 x in set, len(set),和 for x in set。作为一个无序的集合,set不记录元素位置或者插入点。因此,sets不支持 indexing, 或其它类序列的操作。 + +#### python集合概述 + +在set中,对应的set的值的存储是通过结构setentry来保存数据值的; + +``` + +typedef struct { + PyObject *key; + Py_hash_t hash; /* Cached hash code of the key */ +} setentry; +``` + +key就是保存的数据,hash就是保存的数据的hash,便于查找,set也是基于hash表来实现。对应的setentry所对应的set的数据结构如下; + +``` + +typedef struct { + PyObject_HEAD + + Py_ssize_t fill; /* Number active and dummy entries*/ // 包括已经使用的entry与空entry值的总和 + Py_ssize_t used; /* Number active entries */ // 已经使用可用的总量 + + /* The table contains mask + 1 slots, and that's a power of 2. + * We store the mask instead of the size because the mask is more + * frequently needed. + */ + Py_ssize_t mask;                                // 与hash求和的mask + + /* The table points to a fixed-size smalltable for small tables + * or to additional malloc'ed memory for bigger tables. + * The table pointer is never NULL which saves us from repeated + * runtime null-tests. + */ + setentry *table; // 保存数据的数组数组指针 + Py_hash_t hash; /* Only used by frozenset objects */ + Py_ssize_t finger; /* Search finger for pop() */ + + setentry smalltable[PySet_MINSIZE]; // 保存数据的数组 默认初始化为8个元素,通过table指向 + PyObject *weakreflist; /* List of weak references */ +} PySetObject; +``` + +一个set就对应一个PySetObject类型数据,set会根据保存的元素自动调整大小。相关的内存布局如下; + +![内存图片](./python_set.png) + +#### python集合(set)示例 + +示例脚本如下: + +``` +set_a = {1,2}  +set_a.add(3) +set_a.add(4) +set_a.remove(1) +set_a.update({3,}) +set_a.union({1,5}) + +``` + +通过python反汇编获取该脚本的字节码; + +``` +python -m dis set_test.py +``` + +输出的字节码如下所示; + +``` + 1 0 LOAD_CONST 0 (1) + 3 LOAD_CONST 1 (2) + 6 BUILD_SET 2 + 9 STORE_NAME 0 (set_a) + + 2 12 LOAD_NAME 0 (set_a) + 15 LOAD_ATTR 1 (add) + 18 LOAD_CONST 2 (3) + 21 CALL_FUNCTION 1 + 24 POP_TOP + + 3 25 LOAD_NAME 0 (set_a) + 28 LOAD_ATTR 1 (add) + 31 LOAD_CONST 3 (4) + 34 CALL_FUNCTION 1 + 37 POP_TOP + + 4 38 LOAD_NAME 0 (set_a) + 41 LOAD_ATTR 2 (remove) + 44 LOAD_CONST 0 (1) + 47 CALL_FUNCTION 1 + 50 POP_TOP + + 5 51 LOAD_NAME 0 (set_a) + 54 LOAD_ATTR 3 (update) + 57 LOAD_CONST 2 (3) + 60 BUILD_SET 1 + 63 CALL_FUNCTION 1 + 66 POP_TOP + + 6 67 LOAD_NAME 0 (set_a) + 70 LOAD_ATTR 4 (union) + 73 LOAD_CONST 0 (1) + 76 LOAD_CONST 4 (5) + 79 BUILD_SET 2 + 82 CALL_FUNCTION 1 + 85 POP_TOP + 86 LOAD_CONST 5 (None) + 89 RETURN_VALUE +``` + + +通过该字节码指令可知,创建set调用了BUILD_SET指令,初始化完成之后,就调用set的add方法添加元素,调用remove删除元素,调用update来更新集合,通过union来合并集合。接下来就详细分析一下相关的操作流程。 + +##### set的创建与初始化 + +查找BUILD_SET的虚拟机执行函数如下; + +``` +// Python/ceval.c + + TARGET(BUILD_SET) { + PyObject *set = PySet_New(NULL); // 新建并初始化一个set + int err = 0; + int i; + if (set == NULL) + goto error; + for (i = oparg; i > 0; i--) { // 将传入初始化的参数传入 + PyObject *item = PEEK(i); + if (err == 0) + err = PySet_Add(set, item); // 并依次对set进行添加操作 + Py_DECREF(item); + } + STACKADJ(-oparg);                // 移动弹栈 + if (err != 0) { + Py_DECREF(set); + goto error; + } + PUSH(set);                     // 讲set压栈 + DISPATCH();                    // 执行下一条指令 + } + +``` + +此时继续查看PySet_New函数的执行流程; + + +``` +PyObject * +PySet_New(PyObject *iterable) +{ + return make_new_set(&PySet_Type, iterable); +} + +... + + +static PyObject * +make_new_set(PyTypeObject *type, PyObject *iterable) +{ + PySetObject *so; + + so = (PySetObject *)type->tp_alloc(type, 0); // 申请该元素的内存 + if (so == NULL) // 内存申请失败则返回为空 + return NULL; + + so->fill = 0; // 初始化的时候都为0 + so->used = 0; + so->mask = PySet_MINSIZE - 1; // PySet_MINSIZE默认我8,mask为7 + so->table = so->smalltable; // 将保存数据的头指针指向table + so->hash = -1; // 设置hash值为-1 + so->finger = 0; + so->weakreflist = NULL; + + if (iterable != NULL) { // 如果有迭代器 + if (set_update_internal(so, iterable)) { // 将内容更新到so中 + Py_DECREF(so); + return NULL; + } + } + + return (PyObject *)so; // 返回初始化完成的set +} +``` + +从PySet_New的执行流程可知,字典的初始化过程就是初始化相关数据结构。 + +##### set的插入 + +在本例的初始化过程中,由于传入了初始值1,2,所以会在执行字节码指令的时候,执行PySet_Add,该函数的本质与set_a.add(3)本质都调用了更底层set_add_key函数; + +``` + +int +PySet_Add(PyObject *anyset, PyObject *key) +{ + if (!PySet_Check(anyset) && + (!PyFrozenSet_Check(anyset) || Py_REFCNT(anyset) != 1)) { + PyErr_BadInternalCall(); + return -1; + } + return set_add_key((PySetObject *)anyset, key); // 向字典中添加key; +} +``` + +继续查看set_add_key函数的执行过程; + +``` +static int +set_add_key(PySetObject *so, PyObject *key) +{ + Py_hash_t hash; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key); // 获取传入值的hash值 + if (hash == -1) // 如果不能hash则返回-1 + return -1; + } + return set_add_entry(so, key, hash); // 计算完成后添加值 +} +``` + +该函数主要就是检查传入的key是否能够被hash,如果能够被hash则直接返回,如果能被hash则继续调用set_add_entry函数将值加入到set中; + +``` + +static int +set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) +{ + setentry *table; + setentry *freeslot; + setentry *entry; + size_t perturb; + size_t mask; + size_t i; /* Unsigned for defined overflow behavior */ + size_t j; + int cmp; + + /* Pre-increment is necessary to prevent arbitrary code in the rich + comparison from deallocating the key just before the insertion. */ + Py_INCREF(key); // 提高key的引用计数 + + restart: + + mask = so->mask;  // 获取so->mask + i = (size_t)hash & mask;  // 通过传入的hash与mask求索引下标 + + entry = &so->table[i];    // 获取索引对应的值 + if (entry->key == NULL) // 如果获取索引的值没有被使用则直接跳转到found_unused处执行 + goto found_unused; + + freeslot = NULL; + perturb = hash;    // perturb设置为当前hash值 +  + while (1) { + if (entry->hash == hash) { // 如果当前hash值相等 + PyObject *startkey = entry->key;                      // 获取当前key + /* startkey cannot be a dummy because the dummy hash field is -1 */ + assert(startkey != dummy); // 检查key是否为dummy + if (startkey == key) // 如果找到的值与传入需要设置的值相同则跳转到found_active处执行 + goto found_active; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && _PyUnicode_EQ(startkey, key)) // 如果是unicode,通过类型转换检查两个key的内容是否相同,如果不相同则跳转到found_active处 + goto found_active; + table = so->table; // 如果没有找到,则获取当前table的头部节点 + Py_INCREF(startkey); + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ);          // 如果是其他类型的对象则调用比较方法去比较两个key是否相同 + Py_DECREF(startkey); + if (cmp > 0) /* likely */ // 如果找到则跳转到found_active + goto found_active; + if (cmp < 0) + goto comparison_error; // 如果小于0,则是两个类型对比失败 + /* Continuing the search from the current entry only makes + sense if the table and entry are unchanged; otherwise, + we have to restart from the beginning */ + if (table != so->table || entry->key != startkey) // 如果set改变了则重新开始查找 + goto restart; + mask = so->mask; /* help avoid a register spill */    + } + else if (entry->hash == -1) + freeslot = entry;    // 如果不能hash 则设置freeslot + + if (i + LINEAR_PROBES <= mask) {               // 检查当前索引值加上 9小于当前mask + for (j = 0 ; j < LINEAR_PROBES ; j++) { // 循环9次 + entry++;     // 向下一个位置 + if (entry->hash == 0 && entry->key == NULL)              // 如果找到当前hash为空或者key为空的则跳转到found_unused_or_dummy处执行 + goto found_unused_or_dummy; + if (entry->hash == hash) {   // 如果找到的hash值相同 + PyObject *startkey = entry->key; // 获取该值 + assert(startkey != dummy); // 检查是否为dummy + if (startkey == key) // 如果key相同则跳转到found_active处执行 + goto found_active; + if (PyUnicode_CheckExact(startkey) + && PyUnicode_CheckExact(key) + && _PyUnicode_EQ(startkey, key)) // 检查是否为unicode,并比较如果不相同则跳转到found_active + goto found_active; + table = so->table; // 调用key本身的方法比较 + Py_INCREF(startkey); + cmp = PyObject_RichCompareBool(startkey, key, Py_EQ); + Py_DECREF(startkey); + if (cmp > 0) + goto found_active; + if (cmp < 0) + goto comparison_error; + if (table != so->table || entry->key != startkey) + goto restart; + mask = so->mask; + } + else if (entry->hash == -1) + freeslot = entry; + } + } + + perturb >>= PERTURB_SHIFT; // 如果没有找到则获取下一个索引值 + i = (i * 5 + 1 + perturb) & mask; // 右移5位 加上 索引值*5 加1与mask求余获取下一个索引值 + + entry = &so->table[i]; // 获取下一个元素 + if (entry->key == NULL)               // 如果找到为空则直接跳转到found_unused_or_dummy处 + goto found_unused_or_dummy; + } + + found_unused_or_dummy: + if (freeslot == NULL)                                  // 检查freeslot是否为空如果为空则跳转到found_unused处执行即找到了dummy位置 + goto found_unused; + so->used++;                       // 使用数加1 + freeslot->key = key;                                   // 设置key与hash值 + freeslot->hash = hash; + return 0; + + found_unused: + so->fill++;                                        // 使用总数加1 + so->used++;                                        // 使用总数加1  + entry->key = key;                                     // 设置key与hash值 + entry->hash = hash; + if ((size_t)so->fill*5 < mask*3)                           // 检查已经使用的值是否是总数的3/5 + return 0; + return set_table_resize(so, so->used>50000 ? so->used*2 : so->used*4);    // 如果已使用的总数大于3/5则重新调整table,如果set使用的总数超过了50000则扩展为以前的2倍否则就是四倍 + + found_active: + Py_DECREF(key);                                      // 如果找到了该值 则什么也不做 + return 0; + + comparison_error: + Py_DECREF(key);                                      // 如果比较失败则返回-1 + return -1; +} +``` + +此时基本的流程就是通过传入的hash值,如果计算出的索引值,没有值,则直接将该值存入对应的entry中,如果相同则不插入,如果索引对应的值且值不同,则遍历从该索引往后9个位置的值,依次找到有空余位置的值,并将该值设置进去。如果设置该值之后使用的数量占总的申请数量超过了3/5则重新扩充set,扩充的原则就是如果当前的set->used>50000就进行两倍扩充否则就进行四倍扩充。 + +插入的概述如下,默认s初始化为空; + +``` +s.add(1) // index = 1 & 7 = 1 +``` + +![插入1](./set_insert_one.png) + +``` +s.add(2) // index = 2 & 7 = 2 +``` + +![插入2](./set_insert_two.png) + +``` +s.add(7) // index = 9 & 7 = 1 +``` + +![插入9](./set_insert_nine.png) + +大致的set的插入过程执行完毕。 + +##### set的删除 + +set的删除操作主要集中在set_remove()函数上,如下示例; + +``` + +static PyObject * +set_remove(PySetObject *so, PyObject *key) +{ + PyObject *tmpkey; + int rv; + + rv = set_discard_key(so, key); // 将该key设置为dummy + if (rv < 0) { + if (!PySet_Check(key) || !PyErr_ExceptionMatches(PyExc_TypeError)) // 检查是否为set类型 + return NULL; + PyErr_Clear(); + tmpkey = make_new_set(&PyFrozenSet_Type, key);             // 对该值重新初始化为forzenset + if (tmpkey == NULL) + return NULL; + rv = set_discard_key(so, tmpkey);                     // 设置该key为空 + Py_DECREF(tmpkey); + if (rv < 0) + return NULL; + } + + if (rv == DISCARD_NOTFOUND) { // 如果没有找到则报错 + _PyErr_SetKeyError(key); + return NULL; + } + Py_RETURN_NONE; +} +``` + +此时就会调用set_discard_key方法来讲对应的entry设置为dummy;set_discard_key方法如下; + +``` + +static int +set_discard_key(PySetObject *so, PyObject *key) +{ + Py_hash_t hash; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) { + hash = PyObject_Hash(key);  // 检查是否可用hash如果可用则调用set_discard_entry方法 + if (hash == -1) + return -1; + } + return set_discard_entry(so, key, hash); +} +``` + +该函数主要就是做了检查key是否可用hash的检查,此时如果可用hash则调用set_discard_entry方法; + +``` + +static int +set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash) +{ + setentry *entry; + PyObject *old_key; + + entry = set_lookkey(so, key, hash);      // 查找该值 set_lookkey该方法与插入的逻辑类似大家可自行查看 + if (entry == NULL)                 // 如果没有找到则返回-1 + return -1; + if (entry->key == NULL) + return DISCARD_NOTFOUND;           // 找到entry而key为空则返回notfound + old_key = entry->key; // 找到正常值则讲该值对应的entry设置为dummy + entry->key = dummy; + entry->hash = -1; // hash值为-1 + so->used--; // 使用数量减1 但是fill数量未变 + Py_DECREF(old_key);                 // 减少该对象引用 + return DISCARD_FOUND;                // 返回返现 +} +``` + +此时就是查找该值,如果找到该值并将该值设置为dummy,并且将used值减1,此处没有减去fill的数量,从此处可知,fill包括所有曾经申请过的数量。 + + +##### set的resize + +set的resize主要依靠set_table_reseize函数来实现; + +``` +static int +set_table_resize(PySetObject *so, Py_ssize_t minused) +{ + setentry *oldtable, *newtable, *entry; + Py_ssize_t oldmask = so->mask; // 设置旧的mask + size_t newmask; + int is_oldtable_malloced; + setentry small_copy[PySet_MINSIZE]; // 最小的拷贝数组 + + assert(minused >= 0); + + /* Find the smallest table size > minused. */ + /* XXX speed-up with intrinsics */ + size_t newsize = PySet_MINSIZE; + while (newsize <= (size_t)minused) { + newsize <<= 1; // The largest possible value is PY_SSIZE_T_MAX + 1.  // 查找位于minused最大的PySet_MINSIZE的n次方的值 + } + + /* Get space for a new table. */ + oldtable = so->table;                   // 先获取旧的table + assert(oldtable != NULL); + is_oldtable_malloced = oldtable != so->smalltable; + + if (newsize == PySet_MINSIZE) {                  // 如果获取的新大小与PySet_MINSIZE的大小相同 + /* A large table is shrinking, or we can't get any smaller. */ + newtable = so->smalltable;                  // 获取新table的地址 + if (newtable == oldtable) {                 // 如果相同 + if (so->fill == so->used) {              // 如果使用的相同则什么都不做 + /* No dummies, so no point doing anything. */ + return 0; + } + /* We're not going to resize it, but rebuild the + table anyway to purge old dummy entries. + Subtle: This is *necessary* if fill==size, + as set_lookkey needs at least one virgin slot to + terminate failing searches. If fill < size, it's + merely desirable, as dummies slow searches. */ + assert(so->fill > so->used); + memcpy(small_copy, oldtable, sizeof(small_copy)); // 将数据拷贝到set_lookkey中 + oldtable = small_copy;                   + } + } + else { + newtable = PyMem_NEW(setentry, newsize); // 新申请内存 + if (newtable == NULL) {                     // 如果为空则申请内存失败报错 + PyErr_NoMemory(); + return -1; + } + } + + /* Make the set empty, using the new table. */ + assert(newtable != oldtable); // 检查新申请的与就table不同 + memset(newtable, 0, sizeof(setentry) * newsize);        // 新申请的内存置空 + so->mask = newsize - 1; // 设置新的size + so->table = newtable; // 重置table指向新table + + /* Copy the data over; this is refcount-neutral for active entries; + dummy entries aren't copied over, of course */ + newmask = (size_t)so->mask; // 获取新的mask + if (so->fill == so->used) { // 如果使用的与曾经使用的数量相同 + for (entry = oldtable; entry <= oldtable + oldmask; entry++) { + if (entry->key != NULL) { + set_insert_clean(newtable, newmask, entry->key, entry->hash);  // 如果值不为空则插入到新的table中 + } + } + } else { + so->fill = so->used;                        // 如果不相同则重置fill为used的值 + for (entry = oldtable; entry <= oldtable + oldmask; entry++) { + if (entry->key != NULL && entry->key != dummy) {     // 检查如果不为dummy并且key不为空的情况下 + set_insert_clean(newtable, newmask, entry->key, entry->hash);  // 重新插入该列表该值 + } + } + } + + if (is_oldtable_malloced)                       // 如果两个表相同则删除旧table + PyMem_DEL(oldtable); + return 0; // 返回0 +} + +``` + +主要是检查是否table相同并且需要重新resize的值,然后判断是否fill与used相同,如果相同则全部插入,如果不同,则遍历旧table讲不为空并且不为dummy的值插入到新表中; + +``` +static void +set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash) +{ + setentry *entry; + size_t perturb = hash; + size_t i = (size_t)hash & mask;         // 计算索引 + size_t j; + + while (1) { + entry = &table[i]; // 获取当前entry + if (entry->key == NULL) // 如果为空则跳转值found_null设置key与hash + goto found_null; + if (i + LINEAR_PROBES <= mask) { // 如果没有找到空值则通过该索引偏移9位去查找空余位置 + for (j = 0; j < LINEAR_PROBES; j++) { + entry++; + if (entry->key == NULL) // 如果为空则跳转到found_null + goto found_null; + } + } + perturb >>= PERTURB_SHIFT; // 计算下一个索引值继续寻找 + i = (i * 5 + 1 + perturb) & mask; + } + found_null: + entry->key = key; + entry->hash = hash; +} +``` + +set的resize的操作基本如上所述。 + From 3417344bb33d32fd0661d317b52e711c95297551 Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Tue, 4 Jun 2019 19:29:42 +0800 Subject: [PATCH 07/17] Add readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8e0b56..9939338 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,8 @@ gitbook serve - [ ] Python 整数对象 - [ ] Python 字符串 对象 - [ ] Python List 对象 - - [ ] Python Dict 对象 - - [ ] Python Set 对象 + - [x] Python Dict 对象 + - [x] Python Set 对象 - [ ] 实现简版 Python - [ ] Python 虚拟机 - [ ] Python 编译结果 From 42db5be54af31e6b3c3f8d2480cc7ac1e66860f2 Mon Sep 17 00:00:00 2001 From: ltoddy Date: Tue, 28 May 2019 12:32:17 +0800 Subject: [PATCH 08/17] use npm to manage project --- .travis.yml | 4 + README.md | 17 +- package-lock.json | 7282 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 20 + 4 files changed, 7316 insertions(+), 7 deletions(-) create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.travis.yml b/.travis.yml index b10a1cf..4dd3b54 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,14 @@ install: - npm install gitbook-cli -g # 安装 gitbook 插件 - gitbook install + # npm -g 是全局安装, 下面的npm install是安装在项目的node_modules中,这两种构建不冲突 + - npm install # 构建脚本 script: - gitbook build + # 不冲突 + - npm run build # 分支白名单 branches: diff --git a/README.md b/README.md index 225ff9a..c43c0fc 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,11 @@ ## 前置条件 -您的系统上需要安装好 node。 +您的系统上需要安装好 node (会自带npm)。 -## 使用 make 命令 +## 使用 make 或者使用 npm 命令去构建 + +### 使用 make 命令的方式构建: 若您可使用 make 命令,简单执行如下命令进行初始化: @@ -26,19 +28,20 @@ make init make run ``` -## 使用 gitbook 命令 +### 使用 npm 命令的方式构建: + +若您不能使用 make 命令,或想直接使用 npm 命令,执行如下命令进行初始化: -若您不能使用 make 命令,或想直接使用 gitbook 命令,执行如下命令进行初始化: +安装项目依赖: ```console -npm i -g gitbook-cli #可能需要sudo -gitbook install +npm install ``` 执行如下命令运行服务端: ```console -gitbook serve +npm run serve ``` ## 访问 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4cc2f17 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7282 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "align-text": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", + "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", + "requires": { + "kind-of": "^3.0.2", + "longest": "^1.0.1", + "repeat-string": "^1.5.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asciidoctor.js": { + "version": "1.5.3-preview.1", + "resolved": "https://registry.npmjs.org/asciidoctor.js/-/asciidoctor.js-1.5.3-preview.1.tgz", + "integrity": "sha1-BPRflV3tKPS45738fo/TcyvJ0e0=", + "requires": { + "opal-npm-wrapper": "^0.1.1", + "xmlhttprequest": "~1.6.0" + } + }, + "asn1": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=" + }, + "assert-plus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=" + }, + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=" + }, + "async-each": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-0.1.6.tgz", + "integrity": "sha1-tn6Z7c3fllQeRK9WKQzX1cbnBDk=" + }, + "aws-sign2": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bash-color": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/bash-color/-/bash-color-0.0.3.tgz", + "integrity": "sha1-DAiSHsATk6tW6kRPCCXlSTyg5qI=" + }, + "batch": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.5.2.tgz", + "integrity": "sha1-VGVD2+MhGMg8fHyjOh9cXV6pY+k=" + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "bl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", + "requires": { + "readable-stream": "~1.0.26" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "body-parser": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.14.2.tgz", + "integrity": "sha1-EBXLH+LEQ4WCWVgdtTMy+NDPUPk=", + "requires": { + "bytes": "2.2.0", + "content-type": "~1.0.1", + "debug": "~2.2.0", + "depd": "~1.1.0", + "http-errors": "~1.3.1", + "iconv-lite": "0.4.13", + "on-finished": "~2.3.0", + "qs": "5.2.0", + "raw-body": "~2.1.5", + "type-is": "~1.6.10" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "qs": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.2.0.tgz", + "integrity": "sha1-qfMRQq9GjLcrJbMBNrokVoNJFr4=" + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" + }, + "boom": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", + "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", + "requires": { + "hoek": "0.9.x" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "bytes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.2.0.tgz", + "integrity": "sha1-/TVGSkA/b5EXwt42Cez/nK4ABYg=" + }, + "camelcase": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", + "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=" + }, + "caseless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.8.0.tgz", + "integrity": "sha1-W8oogdQUN/VLJAfr40iIx7mtT30=" + }, + "center-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", + "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "requires": { + "align-text": "^0.1.3", + "lazy-cache": "^1.0.3" + } + }, + "cheerio": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", + "integrity": "sha1-dy5wFfLuKZZQltcepBdbdas1SSU=", + "requires": { + "css-select": "~1.0.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "~3.8.1", + "lodash": "^3.2.0" + } + }, + "chokidar": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.0.6.tgz", + "integrity": "sha1-ChwLzh4kmTr8EFpbgeom3aAeI68=", + "requires": { + "anymatch": "^1.1.0", + "arrify": "^1.0.0", + "async-each": "^0.1.5", + "fsevents": "^0.3.8", + "glob-parent": "^1.0.0", + "is-binary-path": "^1.0.0", + "is-glob": "^1.1.3", + "path-is-absolute": "^1.0.0", + "readdirp": "^1.3.0" + } + }, + "clean-css": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-1.1.7.tgz", + "integrity": "sha1-YB75z3ZCuYLLM+/JSIpkRMmGaG4=", + "requires": { + "commander": "2.0.x" + }, + "dependencies": { + "commander": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz", + "integrity": "sha1-0bhvkB+LZL2UG96tr5JFMDk76Sg=" + } + } + }, + "cli-color": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-0.3.3.tgz", + "integrity": "sha1-EtW90Vj/igsNtAEZiRPAPfBp9vU=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.6", + "memoizee": "~0.3.8", + "timers-ext": "0.1" + } + }, + "clipboard": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", + "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "cliui": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", + "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", + "requires": { + "center-align": "^0.1.1", + "right-align": "^0.1.1", + "wordwrap": "0.0.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "requires": { + "delayed-stream": "0.0.5" + } + }, + "commander": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "crc": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.2.1.tgz", + "integrity": "sha1-XZyPt3okXNXsopHl0tAFM0urAII=" + }, + "cryptiles": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", + "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", + "requires": { + "boom": "0.4.x" + } + }, + "css-select": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", + "integrity": "sha1-sRIcpRhI3SZOIkTQWM7iVN7rRLA=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "1.0", + "domutils": "1.4", + "nth-check": "~1.0.0" + } + }, + "css-what": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", + "integrity": "sha1-18wt9FGAZm+Z0rFEYmOUaeAPc2w=" + }, + "cssom": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.0.tgz", + "integrity": "sha1-OG1RNVKP5lwe4bx8TlWjiFTbz3o=" + }, + "ctype": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=" + }, + "d": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz", + "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "datauri": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/datauri/-/datauri-0.2.1.tgz", + "integrity": "sha1-9Oit27PlTj3BLRyIVDuLCxv2kvo=", + "requires": { + "mimer": "*", + "templayed": "*" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=" + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "optional": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "dom-serializer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", + "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "requires": { + "domelementtype": "~1.1.1", + "entities": "~1.1.1" + }, + "dependencies": { + "domelementtype": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", + "integrity": "sha1-CGVRN5bGswYDGFDhdVFrr4C3Km8=", + "requires": { + "domelementtype": "1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, + "es5-ext": { + "version": "0.10.50", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.50.tgz", + "integrity": "sha512-KMzZTPBkeQV/JcSQhI5/z6d9VWJ3EnQ194USTUwIYZ2ZbpN8+SGXQKt1h68EX44+qt+Fzr8DO17vnxrw7c3agw==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "^1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "^0.10.9" + } + } + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "^0.10.9" + } + } + } + }, + "es6-weak-map": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-0.1.4.tgz", + "integrity": "sha1-cGzvnpmqI2undmwjnIueKG6n0ig=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.6", + "es6-iterator": "~0.1.3", + "es6-symbol": "~2.0.1" + }, + "dependencies": { + "es6-iterator": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-0.1.3.tgz", + "integrity": "sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.5", + "es6-symbol": "~2.0.1" + } + }, + "es6-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-2.0.1.tgz", + "integrity": "sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.5" + } + } + } + }, + "escape-string-regexp": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz", + "integrity": "sha1-ni2LJbwlVcMzZyN1DgPwmcJzW7U=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + }, + "dependencies": { + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "^0.10.9" + } + } + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", + "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=" + }, + "form-data": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz", + "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=", + "requires": { + "async": "~0.9.0", + "combined-stream": "~0.0.4", + "mime-types": "~2.0.3" + }, + "dependencies": { + "mime-types": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz", + "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=", + "requires": { + "mime-db": "~1.12.0" + } + } + } + }, + "fs-extra": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.16.5.tgz", + "integrity": "sha1-GtZh+myGyWCM0bSe/G/Og0k5p1A=", + "requires": { + "graceful-fs": "^3.0.5", + "jsonfile": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-0.3.8.tgz", + "integrity": "sha1-mZLxAyySXIKVVNDVmAHcoDE6U1Y=", + "optional": true, + "requires": { + "nan": "^2.0.2" + } + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + } + } + }, + "fstream-ignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.2.tgz", + "integrity": "sha1-GMiR2wG3gqdKe/+Tag8kmXdBx6s=", + "requires": { + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^2.0.1" + }, + "dependencies": { + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "requires": { + "brace-expansion": "^1.0.0" + } + } + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "gitbook": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/gitbook/-/gitbook-2.6.9.tgz", + "integrity": "sha512-GFuOpq5Qv7JktAe9U8LfCkrBRshl0Ymm2eVMz8FuNXr9vkA2TTQrXOHlU04ElfbDIyLdA5Zx5362OnZS1ItNQA==", + "requires": { + "bash-color": "0.0.3", + "cheerio": "0.19.0", + "chokidar": "~1.0.5", + "crc": "3.2.1", + "dom-serializer": "0.1.0", + "escape-string-regexp": "1.0.3", + "fs-extra": "0.16.5", + "fstream-ignore": "1.0.2", + "gitbook-parsers": "0.8.9", + "gitbook-plugin-fontsettings": "1.0.2", + "gitbook-plugin-highlight": "1.0.3", + "gitbook-plugin-livereload": "0.0.1", + "gitbook-plugin-search": "1.1.0", + "gitbook-plugin-sharing": "1.0.1", + "github-slugid": "1.0.0", + "graceful-fs": "3.0.5", + "json-schema-defaults": "0.1.1", + "jsonschema": "1.0.2", + "juice": "1.5.0", + "lodash": "3.10.1", + "merge-defaults": "0.2.1", + "npm": "2.4.1", + "npmi": "0.1.1", + "nunjucks": "2.2.0", + "nunjucks-autoescape": "1.0.0", + "nunjucks-filter": "1.0.0", + "q": "1.0.1", + "request": "2.51.0", + "resolve": "0.6.3", + "semver": "5.0.1", + "spawn-cmd": "0.0.2", + "tiny-lr": "0.2.1", + "tmp": "0.0.24", + "urijs": "1.17.0" + } + }, + "gitbook-asciidoc": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/gitbook-asciidoc/-/gitbook-asciidoc-0.2.4.tgz", + "integrity": "sha1-bhpQldA6juwvEV6+3PwRwKI9qc8=", + "requires": { + "asciidoctor.js": "1.5.3-preview.1", + "cheerio": "^0.19.0", + "lodash": "^3.2.0", + "q": "^1.1.2" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + } + } + }, + "gitbook-cli": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/gitbook-cli/-/gitbook-cli-2.3.2.tgz", + "integrity": "sha512-eyGtkY7jKHhmgpfuvgAP5fZcUob/FBz4Ld0aLRdEmiTrS1RklimN9epzPp75dd4MWpGhYvSbiwxnpyLiv1wh6A==", + "requires": { + "bash-color": "0.0.4", + "commander": "2.11.0", + "fs-extra": "3.0.1", + "lodash": "4.17.4", + "npm": "5.1.0", + "npmi": "1.0.1", + "optimist": "0.6.1", + "q": "1.5.0", + "semver": "5.3.0", + "tmp": "0.0.31", + "user-home": "2.0.0" + }, + "dependencies": { + "bash-color": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/bash-color/-/bash-color-0.0.4.tgz", + "integrity": "sha1-6b6M4zVAytpIgXaMWb1jhlc26RM=" + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "fs-extra": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", + "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "npm": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-5.1.0.tgz", + "integrity": "sha512-pt5ClxEmY/dLpb60SmGQQBKi3nB6Ljx1FXmpoCUdAULlGqGVn2uCyXxPCWFbcuHGthT7qGiaGa1wOfs/UjGYMw==", + "requires": { + "JSONStream": "~1.3.1", + "abbrev": "~1.1.0", + "ansi-regex": "~3.0.0", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "aproba": "~1.1.2", + "archy": "~1.0.0", + "bluebird": "~3.5.0", + "cacache": "~9.2.9", + "call-limit": "~1.1.0", + "chownr": "~1.0.1", + "cmd-shim": "~2.0.2", + "columnify": "~1.5.4", + "config-chain": "~1.1.11", + "debuglog": "*", + "detect-indent": "~5.0.0", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "fs-vacuum": "~1.2.10", + "fs-write-stream-atomic": "~1.0.10", + "fstream": "~1.0.11", + "fstream-npm": "~1.2.1", + "glob": "~7.1.2", + "graceful-fs": "~4.1.11", + "has-unicode": "~2.0.1", + "hosted-git-info": "~2.5.0", + "iferr": "~0.1.5", + "imurmurhash": "*", + "inflight": "~1.0.6", + "inherits": "~2.0.3", + "ini": "~1.3.4", + "init-package-json": "~1.10.1", + "lazy-property": "~1.0.0", + "lockfile": "~1.0.3", + "lodash._baseindexof": "*", + "lodash._baseuniq": "~4.6.0", + "lodash._bindcallback": "*", + "lodash._cacheindexof": "*", + "lodash._createcache": "*", + "lodash._getnative": "*", + "lodash.clonedeep": "~4.5.0", + "lodash.restparam": "*", + "lodash.union": "~4.6.0", + "lodash.uniq": "~4.5.0", + "lodash.without": "~4.4.0", + "lru-cache": "~4.1.1", + "mississippi": "~1.3.0", + "mkdirp": "~0.5.1", + "move-concurrently": "~1.0.1", + "node-gyp": "~3.6.2", + "nopt": "~4.0.1", + "normalize-package-data": "~2.4.0", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "~3.0.0", + "npm-package-arg": "~5.1.2", + "npm-registry-client": "~8.4.0", + "npm-user-validate": "~1.0.0", + "npmlog": "~4.1.2", + "once": "~1.4.0", + "opener": "~1.4.3", + "osenv": "~0.1.4", + "pacote": "~2.7.38", + "path-is-inside": "~1.0.2", + "promise-inflight": "~1.0.1", + "read": "~1.0.7", + "read-cmd-shim": "~1.0.1", + "read-installed": "~4.0.3", + "read-package-json": "~2.0.9", + "read-package-tree": "~5.1.6", + "readable-stream": "~2.3.2", + "readdir-scoped-modules": "*", + "request": "~2.81.0", + "retry": "~0.10.1", + "rimraf": "~2.6.1", + "safe-buffer": "~5.1.1", + "semver": "~5.3.0", + "sha": "~2.0.1", + "slide": "~1.1.6", + "sorted-object": "~2.0.1", + "sorted-union-stream": "~2.1.3", + "ssri": "~4.1.6", + "strip-ansi": "~4.0.0", + "tar": "~2.2.1", + "text-table": "~0.2.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "unique-filename": "~1.1.0", + "unpipe": "~1.0.0", + "update-notifier": "~2.2.0", + "uuid": "~3.1.0", + "validate-npm-package-license": "*", + "validate-npm-package-name": "~3.0.0", + "which": "~1.2.14", + "worker-farm": "~1.3.1", + "wrappy": "~1.0.2", + "write-file-atomic": "~2.1.0" + }, + "dependencies": { + "JSONStream": { + "version": "1.3.1", + "bundled": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "dependencies": { + "jsonparse": { + "version": "1.3.1", + "bundled": true + }, + "through": { + "version": "2.3.8", + "bundled": true + } + } + }, + "abbrev": { + "version": "1.1.0", + "bundled": true + }, + "ansi-regex": { + "version": "3.0.0", + "bundled": true + }, + "ansicolors": { + "version": "0.3.2", + "bundled": true + }, + "ansistyles": { + "version": "0.1.3", + "bundled": true + }, + "aproba": { + "version": "1.1.2", + "bundled": true + }, + "archy": { + "version": "1.0.0", + "bundled": true + }, + "bluebird": { + "version": "3.5.0", + "bundled": true + }, + "cacache": { + "version": "9.2.9", + "bundled": true, + "requires": { + "bluebird": "^3.5.0", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^1.3.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.1", + "ssri": "^4.1.6", + "unique-filename": "^1.1.0", + "y18n": "^3.2.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.1", + "bundled": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + }, + "dependencies": { + "pseudomap": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true + } + } + }, + "y18n": { + "version": "3.2.1", + "bundled": true + } + } + }, + "call-limit": { + "version": "1.1.0", + "bundled": true + }, + "chownr": { + "version": "1.0.1", + "bundled": true + }, + "cmd-shim": { + "version": "2.0.2", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "columnify": { + "version": "1.5.4", + "bundled": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + }, + "wcwidth": { + "version": "1.0.1", + "bundled": true, + "requires": { + "defaults": "^1.0.3" + }, + "dependencies": { + "defaults": { + "version": "1.0.3", + "bundled": true, + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "bundled": true + } + } + } + } + } + } + }, + "config-chain": { + "version": "1.1.11", + "bundled": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + }, + "dependencies": { + "proto-list": { + "version": "1.2.4", + "bundled": true + } + } + }, + "debuglog": { + "version": "1.0.1", + "bundled": true + }, + "detect-indent": { + "version": "5.0.0", + "bundled": true + }, + "dezalgo": { + "version": "1.0.3", + "bundled": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + }, + "dependencies": { + "asap": { + "version": "2.0.5", + "bundled": true + } + } + }, + "editor": { + "version": "1.0.0", + "bundled": true + }, + "fs-vacuum": { + "version": "1.2.10", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fstream": { + "version": "1.0.11", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "fstream-npm": { + "version": "1.2.1", + "bundled": true, + "requires": { + "fstream-ignore": "^1.0.0", + "inherits": "2" + }, + "dependencies": { + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "requires": { + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + } + } + } + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true + } + } + }, + "graceful-fs": { + "version": "4.1.11", + "bundled": true + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true + }, + "hosted-git-info": { + "version": "2.5.0", + "bundled": true + }, + "iferr": { + "version": "0.1.5", + "bundled": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.4", + "bundled": true + }, + "init-package-json": { + "version": "1.10.1", + "bundled": true, + "requires": { + "glob": "^7.1.1", + "npm-package-arg": "^4.0.0 || ^5.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^3.0.0" + }, + "dependencies": { + "promzard": { + "version": "0.3.0", + "bundled": true, + "requires": { + "read": "1" + } + } + } + }, + "lazy-property": { + "version": "1.0.0", + "bundled": true + }, + "lockfile": { + "version": "1.0.3", + "bundled": true + }, + "lodash._baseindexof": { + "version": "3.1.0", + "bundled": true + }, + "lodash._baseuniq": { + "version": "4.6.0", + "bundled": true, + "requires": { + "lodash._createset": "~4.0.0", + "lodash._root": "~3.0.0" + }, + "dependencies": { + "lodash._createset": { + "version": "4.0.3", + "bundled": true + }, + "lodash._root": { + "version": "3.0.1", + "bundled": true + } + } + }, + "lodash._bindcallback": { + "version": "3.0.1", + "bundled": true + }, + "lodash._cacheindexof": { + "version": "3.0.2", + "bundled": true + }, + "lodash._createcache": { + "version": "3.1.2", + "bundled": true, + "requires": { + "lodash._getnative": "^3.0.0" + } + }, + "lodash._getnative": { + "version": "3.9.1", + "bundled": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "bundled": true + }, + "lodash.restparam": { + "version": "3.6.1", + "bundled": true + }, + "lodash.union": { + "version": "4.6.0", + "bundled": true + }, + "lodash.uniq": { + "version": "4.5.0", + "bundled": true + }, + "lodash.without": { + "version": "4.4.0", + "bundled": true + }, + "lru-cache": { + "version": "4.1.1", + "bundled": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + }, + "dependencies": { + "pseudomap": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true + } + } + }, + "mississippi": { + "version": "1.3.0", + "bundled": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^1.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + }, + "duplexify": { + "version": "3.5.0", + "bundled": true, + "requires": { + "end-of-stream": "1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.0.0", + "bundled": true, + "requires": { + "once": "~1.3.0" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "bundled": true, + "requires": { + "wrappy": "1" + } + } + } + }, + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "end-of-stream": { + "version": "1.4.0", + "bundled": true, + "requires": { + "once": "^1.4.0" + } + }, + "flush-write-stream": { + "version": "1.0.2", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "from2": { + "version": "2.3.0", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "parallel-transform": { + "version": "1.1.0", + "bundled": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + }, + "dependencies": { + "cyclist": { + "version": "0.2.2", + "bundled": true + } + } + }, + "pump": { + "version": "1.0.2", + "bundled": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.3.5", + "bundled": true, + "requires": { + "duplexify": "^3.1.2", + "inherits": "^2.0.1", + "pump": "^1.0.0" + } + }, + "stream-each": { + "version": "1.2.0", + "bundled": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + }, + "through2": { + "version": "2.0.3", + "bundled": true, + "requires": { + "readable-stream": "^2.1.5", + "xtend": "~4.0.1" + }, + "dependencies": { + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "bundled": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "copy-concurrently": { + "version": "1.0.3", + "bundled": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "run-queue": { + "version": "1.0.3", + "bundled": true, + "requires": { + "aproba": "^1.1.1" + } + } + } + }, + "node-gyp": { + "version": "3.6.2", + "bundled": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "2", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "requires": { + "abbrev": "1" + } + } + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "requires": { + "builtin-modules": "^1.0.0" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.1", + "bundled": true + } + } + } + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "bundled": true + }, + "npm-install-checks": { + "version": "3.0.0", + "bundled": true, + "requires": { + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "npm-package-arg": { + "version": "5.1.2", + "bundled": true, + "requires": { + "hosted-git-info": "^2.4.2", + "osenv": "^0.1.4", + "semver": "^5.1.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-registry-client": { + "version": "8.4.0", + "bundled": true, + "requires": { + "concat-stream": "^1.5.2", + "graceful-fs": "^4.1.6", + "normalize-package-data": "~1.0.1 || ^2.0.0", + "npm-package-arg": "^3.0.0 || ^4.0.0 || ^5.0.0", + "npmlog": "2 || ^3.1.0 || ^4.0.0", + "once": "^1.3.3", + "request": "^2.74.0", + "retry": "^0.10.0", + "semver": "2 >=2.2.1 || 3.x || 4 || 5", + "slide": "^1.1.3", + "ssri": "^4.1.2" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + } + } + }, + "npm-user-validate": { + "version": "1.0.0", + "bundled": true + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + }, + "dependencies": { + "are-we-there-yet": { + "version": "1.1.4", + "bundled": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "delegates": { + "version": "1.0.0", + "bundled": true + } + } + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "bundled": true + } + } + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + }, + "wide-align": { + "version": "1.1.2", + "bundled": true, + "requires": { + "string-width": "^1.0.2" + } + } + } + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true + } + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.4.3", + "bundled": true + }, + "osenv": { + "version": "0.1.4", + "bundled": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.2", + "bundled": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true + } + } + }, + "pacote": { + "version": "2.7.38", + "bundled": true, + "requires": { + "bluebird": "^3.5.0", + "cacache": "^9.2.9", + "glob": "^7.1.2", + "lru-cache": "^4.1.1", + "make-fetch-happen": "^2.4.13", + "minimatch": "^3.0.4", + "mississippi": "^1.2.0", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^5.1.2", + "npm-pick-manifest": "^1.0.4", + "osenv": "^0.1.4", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^4.0.0", + "safe-buffer": "^5.1.1", + "semver": "^5.3.0", + "ssri": "^4.1.6", + "tar-fs": "^1.15.3", + "tar-stream": "^1.5.4", + "unique-filename": "^1.1.0", + "which": "^1.2.12" + }, + "dependencies": { + "make-fetch-happen": { + "version": "2.4.13", + "bundled": true, + "requires": { + "agentkeepalive": "^3.3.0", + "cacache": "^9.2.9", + "http-cache-semantics": "^3.7.3", + "http-proxy-agent": "^2.0.0", + "https-proxy-agent": "^2.0.0", + "lru-cache": "^4.1.1", + "mississippi": "^1.2.0", + "node-fetch-npm": "^2.0.1", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^3.0.0", + "ssri": "^4.1.6" + }, + "dependencies": { + "agentkeepalive": { + "version": "3.3.0", + "bundled": true, + "requires": { + "humanize-ms": "^1.2.1" + }, + "dependencies": { + "humanize-ms": { + "version": "1.2.1", + "bundled": true, + "requires": { + "ms": "^2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "http-cache-semantics": { + "version": "3.7.3", + "bundled": true + }, + "http-proxy-agent": { + "version": "2.0.0", + "bundled": true, + "requires": { + "agent-base": "4", + "debug": "2" + }, + "dependencies": { + "agent-base": { + "version": "4.1.0", + "bundled": true, + "requires": { + "es6-promisify": "^5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "^4.0.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.1.1", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "https-proxy-agent": { + "version": "2.0.0", + "bundled": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^2.4.1" + }, + "dependencies": { + "agent-base": { + "version": "4.1.0", + "bundled": true, + "requires": { + "es6-promisify": "^5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "^4.0.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.1.1", + "bundled": true + } + } + } + } + }, + "debug": { + "version": "2.6.8", + "bundled": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "bundled": true + } + } + } + } + }, + "node-fetch-npm": { + "version": "2.0.1", + "bundled": true, + "requires": { + "encoding": "^0.1.11", + "json-parse-helpfulerror": "^1.0.3", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "encoding": { + "version": "0.1.12", + "bundled": true, + "requires": { + "iconv-lite": "~0.4.13" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.18", + "bundled": true + } + } + }, + "json-parse-helpfulerror": { + "version": "1.0.3", + "bundled": true, + "requires": { + "jju": "^1.1.0" + }, + "dependencies": { + "jju": { + "version": "1.3.0", + "bundled": true + } + } + } + } + }, + "socks-proxy-agent": { + "version": "3.0.0", + "bundled": true, + "requires": { + "agent-base": "^4.0.1", + "socks": "^1.1.10" + }, + "dependencies": { + "agent-base": { + "version": "4.1.0", + "bundled": true, + "requires": { + "es6-promisify": "^5.0.0" + }, + "dependencies": { + "es6-promisify": { + "version": "5.0.0", + "bundled": true, + "requires": { + "es6-promise": "^4.0.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.1.1", + "bundled": true + } + } + } + } + }, + "socks": { + "version": "1.1.10", + "bundled": true, + "requires": { + "ip": "^1.1.4", + "smart-buffer": "^1.0.13" + }, + "dependencies": { + "ip": { + "version": "1.1.5", + "bundled": true + }, + "smart-buffer": { + "version": "1.1.15", + "bundled": true + } + } + } + } + } + } + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "requires": { + "brace-expansion": "^1.1.7" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.8", + "bundled": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "npm-pick-manifest": { + "version": "1.0.4", + "bundled": true, + "requires": { + "npm-package-arg": "^5.1.2", + "semver": "^5.3.0" + } + }, + "promise-retry": { + "version": "1.1.1", + "bundled": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + }, + "dependencies": { + "err-code": { + "version": "1.1.2", + "bundled": true + } + } + }, + "protoduck": { + "version": "4.0.0", + "bundled": true, + "requires": { + "genfun": "^4.0.1" + }, + "dependencies": { + "genfun": { + "version": "4.0.1", + "bundled": true + } + } + }, + "tar-fs": { + "version": "1.15.3", + "bundled": true, + "requires": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + }, + "dependencies": { + "pump": { + "version": "1.0.2", + "bundled": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.0", + "bundled": true, + "requires": { + "once": "^1.4.0" + } + } + } + } + } + }, + "tar-stream": { + "version": "1.5.4", + "bundled": true, + "requires": { + "bl": "^1.0.0", + "end-of-stream": "^1.0.0", + "readable-stream": "^2.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "bl": { + "version": "1.2.1", + "bundled": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "end-of-stream": { + "version": "1.4.0", + "bundled": true, + "requires": { + "once": "^1.4.0" + } + }, + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + } + } + }, + "path-is-inside": { + "version": "1.0.2", + "bundled": true + }, + "promise-inflight": { + "version": "1.0.1", + "bundled": true + }, + "read": { + "version": "1.0.7", + "bundled": true, + "requires": { + "mute-stream": "~0.0.4" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.7", + "bundled": true + } + } + }, + "read-cmd-shim": { + "version": "1.0.1", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "read-installed": { + "version": "4.0.3", + "bundled": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "dependencies": { + "util-extend": { + "version": "1.0.3", + "bundled": true + } + } + }, + "read-package-json": { + "version": "2.0.9", + "bundled": true, + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-helpfulerror": "^1.0.2", + "normalize-package-data": "^2.0.0" + }, + "dependencies": { + "json-parse-helpfulerror": { + "version": "1.0.3", + "bundled": true, + "requires": { + "jju": "^1.1.0" + }, + "dependencies": { + "jju": { + "version": "1.3.0", + "bundled": true + } + } + } + } + }, + "read-package-tree": { + "version": "5.1.6", + "bundled": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "once": "^1.3.0", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.2", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "safe-buffer": "~5.1.0", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true + }, + "string_decoder": { + "version": "1.0.3", + "bundled": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + } + } + }, + "readdir-scoped-modules": { + "version": "1.0.2", + "bundled": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "request": { + "version": "2.81.0", + "bundled": true, + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~4.2.1", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "performance-now": "^0.2.0", + "qs": "~6.4.0", + "safe-buffer": "^5.0.1", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.0.0" + }, + "dependencies": { + "aws-sign2": { + "version": "0.6.0", + "bundled": true + }, + "aws4": { + "version": "1.6.0", + "bundled": true + }, + "caseless": { + "version": "0.12.0", + "bundled": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "requires": { + "delayed-stream": "~1.0.0" + }, + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "bundled": true + } + } + }, + "extend": { + "version": "3.0.1", + "bundled": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true + }, + "form-data": { + "version": "2.1.4", + "bundled": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + }, + "dependencies": { + "asynckit": { + "version": "0.4.0", + "bundled": true + } + } + }, + "har-validator": { + "version": "4.2.1", + "bundled": true, + "requires": { + "ajv": "^4.9.1", + "har-schema": "^1.0.5" + }, + "dependencies": { + "ajv": { + "version": "4.11.8", + "bundled": true, + "requires": { + "co": "^4.6.0", + "json-stable-stringify": "^1.0.1" + }, + "dependencies": { + "co": { + "version": "4.6.0", + "bundled": true + }, + "json-stable-stringify": { + "version": "1.0.1", + "bundled": true, + "requires": { + "jsonify": "~0.0.0" + }, + "dependencies": { + "jsonify": { + "version": "0.0.0", + "bundled": true + } + } + } + } + }, + "har-schema": { + "version": "1.0.5", + "bundled": true + } + } + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + }, + "dependencies": { + "boom": { + "version": "2.10.1", + "bundled": true, + "requires": { + "hoek": "2.x.x" + } + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "requires": { + "boom": "2.x.x" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "requires": { + "hoek": "2.x.x" + } + } + } + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "bundled": true + }, + "jsprim": { + "version": "1.4.0", + "bundled": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.0.2", + "json-schema": "0.2.3", + "verror": "1.3.6" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "bundled": true + }, + "extsprintf": { + "version": "1.0.2", + "bundled": true + }, + "json-schema": { + "version": "0.2.3", + "bundled": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "requires": { + "extsprintf": "1.0.2" + } + } + } + }, + "sshpk": { + "version": "1.13.1", + "bundled": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "asn1": { + "version": "0.2.3", + "bundled": true + }, + "assert-plus": { + "version": "1.0.0", + "bundled": true + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "bundled": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "dashdash": { + "version": "1.14.1", + "bundled": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "getpass": { + "version": "0.1.7", + "bundled": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true + }, + "tweetnacl": { + "version": "0.14.5", + "bundled": true, + "optional": true + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true + }, + "mime-types": { + "version": "2.1.15", + "bundled": true, + "requires": { + "mime-db": "~1.27.0" + }, + "dependencies": { + "mime-db": { + "version": "1.27.0", + "bundled": true + } + } + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true + }, + "performance-now": { + "version": "0.2.0", + "bundled": true + }, + "qs": { + "version": "6.4.0", + "bundled": true + }, + "stringstream": { + "version": "0.0.5", + "bundled": true + }, + "tough-cookie": { + "version": "2.3.2", + "bundled": true, + "requires": { + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "bundled": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "bundled": true, + "requires": { + "safe-buffer": "^5.0.1" + } + } + } + }, + "retry": { + "version": "0.10.1", + "bundled": true + }, + "rimraf": { + "version": "2.6.1", + "bundled": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true + }, + "semver": { + "version": "5.3.0", + "bundled": true + }, + "sha": { + "version": "2.0.1", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "readable-stream": "^2.0.2" + } + }, + "slide": { + "version": "1.1.6", + "bundled": true + }, + "sorted-object": { + "version": "2.0.1", + "bundled": true + }, + "sorted-union-stream": { + "version": "2.1.3", + "bundled": true, + "requires": { + "from2": "^1.3.0", + "stream-iterate": "^1.1.0" + }, + "dependencies": { + "from2": { + "version": "1.3.0", + "bundled": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~1.1.10" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.14", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "0.0.1", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + } + } + } + } + }, + "stream-iterate": { + "version": "1.2.0", + "bundled": true, + "requires": { + "readable-stream": "^2.1.5", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "stream-shift": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "ssri": { + "version": "4.1.6", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "requires": { + "ansi-regex": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true + } + } + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + }, + "dependencies": { + "block-stream": { + "version": "0.0.9", + "bundled": true, + "requires": { + "inherits": "~2.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true + }, + "umask": { + "version": "1.1.0", + "bundled": true + }, + "unique-filename": { + "version": "1.1.0", + "bundled": true, + "requires": { + "unique-slug": "^2.0.0" + }, + "dependencies": { + "unique-slug": { + "version": "2.0.0", + "bundled": true, + "requires": { + "imurmurhash": "^0.1.4" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "bundled": true + }, + "update-notifier": { + "version": "2.2.0", + "bundled": true, + "requires": { + "boxen": "^1.0.0", + "chalk": "^1.0.0", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "boxen": { + "version": "1.1.0", + "bundled": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^1.1.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^0.1.0", + "widest-line": "^1.0.0" + }, + "dependencies": { + "ansi-align": { + "version": "2.0.0", + "bundled": true, + "requires": { + "string-width": "^2.0.0" + } + }, + "camelcase": { + "version": "4.1.0", + "bundled": true + }, + "cli-boxes": { + "version": "1.0.0", + "bundled": true + }, + "string-width": { + "version": "2.1.0", + "bundled": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "term-size": { + "version": "0.1.1", + "bundled": true, + "requires": { + "execa": "^0.4.0" + }, + "dependencies": { + "execa": { + "version": "0.4.0", + "bundled": true, + "requires": { + "cross-spawn-async": "^2.1.1", + "is-stream": "^1.1.0", + "npm-run-path": "^1.0.0", + "object-assign": "^4.0.1", + "path-key": "^1.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn-async": { + "version": "2.2.5", + "bundled": true, + "requires": { + "lru-cache": "^4.0.0", + "which": "^1.2.8" + } + }, + "is-stream": { + "version": "1.1.0", + "bundled": true + }, + "npm-run-path": { + "version": "1.0.0", + "bundled": true, + "requires": { + "path-key": "^1.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "bundled": true + }, + "path-key": { + "version": "1.0.0", + "bundled": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "widest-line": { + "version": "1.0.0", + "bundled": true, + "requires": { + "string-width": "^1.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "bundled": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "code-point-at": { + "version": "1.1.0", + "bundled": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "requires": { + "number-is-nan": "^1.0.0" + }, + "dependencies": { + "number-is-nan": { + "version": "1.0.1", + "bundled": true + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + } + } + } + } + } + } + }, + "chalk": { + "version": "1.1.3", + "bundled": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "bundled": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true + } + } + }, + "supports-color": { + "version": "2.0.0", + "bundled": true + } + } + }, + "configstore": { + "version": "3.1.0", + "bundled": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "dot-prop": { + "version": "4.1.1", + "bundled": true, + "requires": { + "is-obj": "^1.0.0" + }, + "dependencies": { + "is-obj": { + "version": "1.0.1", + "bundled": true + } + } + }, + "make-dir": { + "version": "1.0.0", + "bundled": true, + "requires": { + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "bundled": true + } + } + }, + "unique-string": { + "version": "1.0.0", + "bundled": true, + "requires": { + "crypto-random-string": "^1.0.0" + }, + "dependencies": { + "crypto-random-string": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "import-lazy": { + "version": "2.1.0", + "bundled": true + }, + "is-npm": { + "version": "1.0.0", + "bundled": true + }, + "latest-version": { + "version": "3.1.0", + "bundled": true, + "requires": { + "package-json": "^4.0.0" + }, + "dependencies": { + "package-json": { + "version": "4.0.1", + "bundled": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^5.1.0" + }, + "dependencies": { + "got": { + "version": "6.7.1", + "bundled": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "create-error-class": { + "version": "3.0.2", + "bundled": true, + "requires": { + "capture-stack-trace": "^1.0.0" + }, + "dependencies": { + "capture-stack-trace": { + "version": "1.0.0", + "bundled": true + } + } + }, + "duplexer3": { + "version": "0.1.4", + "bundled": true + }, + "get-stream": { + "version": "3.0.0", + "bundled": true + }, + "is-redirect": { + "version": "1.0.0", + "bundled": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "bundled": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true + }, + "lowercase-keys": { + "version": "1.0.0", + "bundled": true + }, + "timed-out": { + "version": "4.0.1", + "bundled": true + }, + "unzip-response": { + "version": "2.0.1", + "bundled": true + }, + "url-parse-lax": { + "version": "1.0.0", + "bundled": true, + "requires": { + "prepend-http": "^1.0.1" + }, + "dependencies": { + "prepend-http": { + "version": "1.0.4", + "bundled": true + } + } + } + } + }, + "registry-auth-token": { + "version": "3.3.1", + "bundled": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "rc": { + "version": "1.2.1", + "bundled": true, + "requires": { + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "deep-extend": { + "version": "0.4.2", + "bundled": true + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + } + } + } + } + }, + "registry-url": { + "version": "3.1.0", + "bundled": true, + "requires": { + "rc": "^1.0.1" + }, + "dependencies": { + "rc": { + "version": "1.2.1", + "bundled": true, + "requires": { + "deep-extend": "~0.4.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "deep-extend": { + "version": "0.4.2", + "bundled": true + }, + "minimist": { + "version": "1.2.0", + "bundled": true + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true + } + } + } + } + } + } + } + } + }, + "semver-diff": { + "version": "2.1.0", + "bundled": true, + "requires": { + "semver": "^5.0.3" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "bundled": true + } + } + }, + "uuid": { + "version": "3.1.0", + "bundled": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "bundled": true, + "requires": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "bundled": true, + "requires": { + "spdx-license-ids": "^1.0.2" + }, + "dependencies": { + "spdx-license-ids": { + "version": "1.2.2", + "bundled": true + } + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "bundled": true + } + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "bundled": true, + "requires": { + "builtins": "^1.0.3" + }, + "dependencies": { + "builtins": { + "version": "1.0.3", + "bundled": true + } + } + }, + "which": { + "version": "1.2.14", + "bundled": true, + "requires": { + "isexe": "^2.0.0" + }, + "dependencies": { + "isexe": { + "version": "2.0.0", + "bundled": true + } + } + }, + "worker-farm": { + "version": "1.3.1", + "bundled": true, + "requires": { + "errno": ">=0.1.1 <0.2.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + }, + "dependencies": { + "errno": { + "version": "0.1.4", + "bundled": true, + "requires": { + "prr": "~0.0.0" + }, + "dependencies": { + "prr": { + "version": "0.0.0", + "bundled": true + } + } + }, + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "write-file-atomic": { + "version": "2.1.0", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + } + } + }, + "npmi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npmi/-/npmi-1.0.1.tgz", + "integrity": "sha1-FddpJzVHVF5oCdzwzhiu1IsCkOI=", + "requires": { + "npm": "^2.1.12", + "semver": "^4.1.0" + }, + "dependencies": { + "npm": { + "version": "2.15.12", + "resolved": "https://registry.npmjs.org/npm/-/npm-2.15.12.tgz", + "integrity": "sha1-33w+1aJ3w/nUtdgZsFMR0QogCuY=", + "requires": { + "abbrev": "~1.0.9", + "ansi": "~0.3.1", + "ansi-regex": "*", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "archy": "~1.0.0", + "async-some": "~1.0.2", + "block-stream": "0.0.9", + "char-spinner": "~1.0.1", + "chmodr": "~1.0.2", + "chownr": "~1.0.1", + "cmd-shim": "~2.0.2", + "columnify": "~1.5.4", + "config-chain": "~1.1.10", + "dezalgo": "~1.0.3", + "editor": "~1.0.0", + "fs-vacuum": "~1.2.9", + "fs-write-stream-atomic": "~1.0.8", + "fstream": "~1.0.10", + "fstream-npm": "~1.1.1", + "github-url-from-git": "~1.4.0", + "github-url-from-username-repo": "~1.0.2", + "glob": "~7.0.6", + "graceful-fs": "~4.1.6", + "hosted-git-info": "~2.1.5", + "imurmurhash": "*", + "inflight": "~1.0.4", + "inherits": "~2.0.3", + "ini": "~1.3.4", + "init-package-json": "~1.9.4", + "lockfile": "~1.0.1", + "lru-cache": "~4.0.1", + "minimatch": "~3.0.3", + "mkdirp": "~0.5.1", + "node-gyp": "~3.6.0", + "nopt": "~3.0.6", + "normalize-git-url": "~3.0.2", + "normalize-package-data": "~2.3.5", + "npm-cache-filename": "~1.0.2", + "npm-install-checks": "~1.0.7", + "npm-package-arg": "~4.1.0", + "npm-registry-client": "~7.2.1", + "npm-user-validate": "~0.1.5", + "npmlog": "~2.0.4", + "once": "~1.4.0", + "opener": "~1.4.1", + "osenv": "~0.1.3", + "path-is-inside": "~1.0.0", + "read": "~1.0.7", + "read-installed": "~4.0.3", + "read-package-json": "~2.0.4", + "readable-stream": "~2.1.5", + "realize-package-specifier": "~3.0.1", + "request": "~2.74.0", + "retry": "~0.10.0", + "rimraf": "~2.5.4", + "semver": "~5.1.0", + "sha": "~2.0.1", + "slide": "~1.1.6", + "sorted-object": "~2.0.0", + "spdx-license-ids": "~1.2.2", + "strip-ansi": "~3.0.1", + "tar": "~2.2.1", + "text-table": "~0.2.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "validate-npm-package-license": "~3.0.1", + "validate-npm-package-name": "~2.2.2", + "which": "~1.2.11", + "wrappy": "~1.0.2", + "write-file-atomic": "~1.1.4" + }, + "dependencies": { + "abbrev": { + "version": "1.0.9", + "bundled": true + }, + "ansi": { + "version": "0.3.1", + "bundled": true + }, + "ansi-regex": { + "version": "2.0.0", + "bundled": true + }, + "ansicolors": { + "version": "0.3.2", + "bundled": true + }, + "ansistyles": { + "version": "0.1.3", + "bundled": true + }, + "archy": { + "version": "1.0.0", + "bundled": true + }, + "async-some": { + "version": "1.0.2", + "bundled": true, + "requires": { + "dezalgo": "^1.0.2" + } + }, + "block-stream": { + "version": "0.0.9", + "bundled": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "char-spinner": { + "version": "1.0.1", + "bundled": true + }, + "chmodr": { + "version": "1.0.2", + "bundled": true + }, + "chownr": { + "version": "1.0.1", + "bundled": true + }, + "cmd-shim": { + "version": "2.0.2", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "columnify": { + "version": "1.5.4", + "bundled": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "wcwidth": { + "version": "1.0.0", + "bundled": true, + "requires": { + "defaults": "^1.0.0" + }, + "dependencies": { + "defaults": { + "version": "1.0.3", + "bundled": true, + "requires": { + "clone": "^1.0.2" + }, + "dependencies": { + "clone": { + "version": "1.0.2", + "bundled": true + } + } + } + } + } + } + }, + "config-chain": { + "version": "1.1.10", + "bundled": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + }, + "dependencies": { + "proto-list": { + "version": "1.2.4", + "bundled": true + } + } + }, + "dezalgo": { + "version": "1.0.3", + "bundled": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + }, + "dependencies": { + "asap": { + "version": "2.0.3", + "bundled": true + } + } + }, + "editor": { + "version": "1.0.0", + "bundled": true + }, + "fs-vacuum": { + "version": "1.2.9", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.8", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + }, + "dependencies": { + "iferr": { + "version": "0.1.5", + "bundled": true + } + } + }, + "fstream": { + "version": "1.0.10", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "fstream-npm": { + "version": "1.1.1", + "bundled": true, + "requires": { + "fstream-ignore": "^1.0.0", + "inherits": "2" + }, + "dependencies": { + "fstream-ignore": { + "version": "1.0.5", + "bundled": true, + "requires": { + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^3.0.0" + } + } + } + }, + "github-url-from-git": { + "version": "1.4.0", + "bundled": true + }, + "github-url-from-username-repo": { + "version": "1.0.2", + "bundled": true + }, + "glob": { + "version": "7.0.6", + "bundled": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "fs.realpath": { + "version": "1.0.0", + "bundled": true + }, + "path-is-absolute": { + "version": "1.0.0", + "bundled": true + } + } + }, + "graceful-fs": { + "version": "4.1.6", + "bundled": true + }, + "hosted-git-info": { + "version": "2.1.5", + "bundled": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true + }, + "inflight": { + "version": "1.0.5", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true + }, + "ini": { + "version": "1.3.4", + "bundled": true + }, + "init-package-json": { + "version": "1.9.4", + "bundled": true, + "requires": { + "glob": "^6.0.0", + "npm-package-arg": "^4.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^2.0.1" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "bundled": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "path-is-absolute": { + "version": "1.0.0", + "bundled": true + } + } + }, + "promzard": { + "version": "0.3.0", + "bundled": true, + "requires": { + "read": "1" + } + } + } + }, + "lockfile": { + "version": "1.0.1", + "bundled": true + }, + "lru-cache": { + "version": "4.0.1", + "bundled": true, + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + }, + "dependencies": { + "pseudomap": { + "version": "1.0.2", + "bundled": true + }, + "yallist": { + "version": "2.0.0", + "bundled": true + } + } + }, + "minimatch": { + "version": "3.0.3", + "bundled": true, + "requires": { + "brace-expansion": "^1.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.1.6", + "bundled": true, + "requires": { + "balanced-match": "^0.4.1", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "0.4.2", + "bundled": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true + } + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "node-gyp": { + "version": "3.6.0", + "bundled": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "2", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "bundled": true + } + } + }, + "nopt": { + "version": "3.0.6", + "bundled": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-git-url": { + "version": "3.0.2", + "bundled": true + }, + "normalize-package-data": { + "version": "2.3.5", + "bundled": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "requires": { + "builtin-modules": "^1.0.0" + }, + "dependencies": { + "builtin-modules": { + "version": "1.1.0", + "bundled": true + } + } + } + } + }, + "npm-cache-filename": { + "version": "1.0.2", + "bundled": true + }, + "npm-install-checks": { + "version": "1.0.7", + "bundled": true, + "requires": { + "npmlog": "0.1 || 1 || 2", + "semver": "^2.3.0 || 3.x || 4 || 5" + } + }, + "npm-package-arg": { + "version": "4.1.0", + "bundled": true, + "requires": { + "hosted-git-info": "^2.1.4", + "semver": "4 || 5" + } + }, + "npm-registry-client": { + "version": "7.2.1", + "bundled": true, + "requires": { + "concat-stream": "^1.5.2", + "graceful-fs": "^4.1.6", + "normalize-package-data": "~1.0.1 || ^2.0.0", + "npm-package-arg": "^3.0.0 || ^4.0.0", + "npmlog": "~2.0.0 || ~3.1.0", + "once": "^1.3.3", + "request": "^2.74.0", + "retry": "^0.10.0", + "semver": "2 >=2.2.1 || 3.x || 4 || 5", + "slide": "^1.1.3" + }, + "dependencies": { + "concat-stream": { + "version": "1.5.2", + "bundled": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + } + } + }, + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + }, + "retry": { + "version": "0.10.0", + "bundled": true + } + } + }, + "npm-user-validate": { + "version": "0.1.5", + "bundled": true + }, + "npmlog": { + "version": "2.0.4", + "bundled": true, + "requires": { + "ansi": "~0.3.1", + "are-we-there-yet": "~1.1.2", + "gauge": "~1.2.5" + }, + "dependencies": { + "are-we-there-yet": { + "version": "1.1.2", + "bundled": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.0 || ^1.1.13" + }, + "dependencies": { + "delegates": { + "version": "1.0.0", + "bundled": true + } + } + }, + "gauge": { + "version": "1.2.7", + "bundled": true, + "requires": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + }, + "dependencies": { + "has-unicode": { + "version": "2.0.0", + "bundled": true + }, + "lodash._baseslice": { + "version": "4.0.0", + "bundled": true + }, + "lodash._basetostring": { + "version": "4.12.0", + "bundled": true + }, + "lodash.pad": { + "version": "4.4.0", + "bundled": true, + "requires": { + "lodash._baseslice": "~4.0.0", + "lodash._basetostring": "~4.12.0", + "lodash.tostring": "^4.0.0" + } + }, + "lodash.padend": { + "version": "4.5.0", + "bundled": true, + "requires": { + "lodash._baseslice": "~4.0.0", + "lodash._basetostring": "~4.12.0", + "lodash.tostring": "^4.0.0" + } + }, + "lodash.padstart": { + "version": "4.5.0", + "bundled": true, + "requires": { + "lodash._baseslice": "~4.0.0", + "lodash._basetostring": "~4.12.0", + "lodash.tostring": "^4.0.0" + } + }, + "lodash.tostring": { + "version": "4.1.4", + "bundled": true + } + } + } + } + }, + "once": { + "version": "1.4.0", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.4.1", + "bundled": true + }, + "osenv": { + "version": "0.1.3", + "bundled": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + }, + "dependencies": { + "os-homedir": { + "version": "1.0.0", + "bundled": true + }, + "os-tmpdir": { + "version": "1.0.1", + "bundled": true + } + } + }, + "path-is-inside": { + "version": "1.0.1", + "bundled": true + }, + "read": { + "version": "1.0.7", + "bundled": true, + "requires": { + "mute-stream": "~0.0.4" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.5", + "bundled": true + } + } + }, + "read-installed": { + "version": "4.0.3", + "bundled": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "^4.1.2", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "dependencies": { + "debuglog": { + "version": "1.0.1", + "bundled": true + }, + "readdir-scoped-modules": { + "version": "1.0.2", + "bundled": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "util-extend": { + "version": "1.0.1", + "bundled": true + } + } + }, + "read-package-json": { + "version": "2.0.4", + "bundled": true, + "requires": { + "glob": "^6.0.0", + "graceful-fs": "^4.1.2", + "json-parse-helpfulerror": "^1.0.2", + "normalize-package-data": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "bundled": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "path-is-absolute": { + "version": "1.0.0", + "bundled": true + } + } + }, + "json-parse-helpfulerror": { + "version": "1.0.3", + "bundled": true, + "requires": { + "jju": "^1.1.0" + }, + "dependencies": { + "jju": { + "version": "1.3.0", + "bundled": true + } + } + } + } + }, + "readable-stream": { + "version": "2.1.5", + "bundled": true, + "requires": { + "buffer-shims": "^1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "buffer-shims": { + "version": "1.0.0", + "bundled": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + } + } + }, + "realize-package-specifier": { + "version": "3.0.1", + "bundled": true, + "requires": { + "dezalgo": "^1.0.1", + "npm-package-arg": "^4.0.0" + } + }, + "request": { + "version": "2.74.0", + "bundled": true, + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "bl": "~1.1.2", + "caseless": "~0.11.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~1.0.0-rc4", + "har-validator": "~2.0.6", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "node-uuid": "~1.4.7", + "oauth-sign": "~0.8.1", + "qs": "~6.2.0", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "~0.4.1" + }, + "dependencies": { + "aws-sign2": { + "version": "0.6.0", + "bundled": true + }, + "aws4": { + "version": "1.4.1", + "bundled": true + }, + "bl": { + "version": "1.1.2", + "bundled": true, + "requires": { + "readable-stream": "~2.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.6", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "bundled": true + }, + "isarray": { + "version": "1.0.0", + "bundled": true + }, + "process-nextick-args": { + "version": "1.0.7", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + } + } + } + } + }, + "caseless": { + "version": "0.11.0", + "bundled": true + }, + "combined-stream": { + "version": "1.0.5", + "bundled": true, + "requires": { + "delayed-stream": "~1.0.0" + }, + "dependencies": { + "delayed-stream": { + "version": "1.0.0", + "bundled": true + } + } + }, + "extend": { + "version": "3.0.0", + "bundled": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true + }, + "form-data": { + "version": "1.0.0-rc4", + "bundled": true, + "requires": { + "async": "^1.5.2", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.10" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "bundled": true + } + } + }, + "har-validator": { + "version": "2.0.6", + "bundled": true, + "requires": { + "chalk": "^1.1.1", + "commander": "^2.9.0", + "is-my-json-valid": "^2.12.4", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "bundled": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "bundled": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "bundled": true + }, + "has-ansi": { + "version": "2.0.0", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "bundled": true + } + } + }, + "commander": { + "version": "2.9.0", + "bundled": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + }, + "dependencies": { + "graceful-readlink": { + "version": "1.0.1", + "bundled": true + } + } + }, + "is-my-json-valid": { + "version": "2.13.1", + "bundled": true, + "requires": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "jsonpointer": "2.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "generate-function": { + "version": "2.0.0", + "bundled": true + }, + "generate-object-property": { + "version": "1.2.0", + "bundled": true, + "requires": { + "is-property": "^1.0.0" + }, + "dependencies": { + "is-property": { + "version": "1.0.2", + "bundled": true + } + } + }, + "jsonpointer": { + "version": "2.0.0", + "bundled": true + }, + "xtend": { + "version": "4.0.1", + "bundled": true + } + } + }, + "pinkie-promise": { + "version": "2.0.1", + "bundled": true, + "requires": { + "pinkie": "^2.0.0" + }, + "dependencies": { + "pinkie": { + "version": "2.0.4", + "bundled": true + } + } + } + } + }, + "hawk": { + "version": "3.1.3", + "bundled": true, + "requires": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + }, + "dependencies": { + "boom": { + "version": "2.10.1", + "bundled": true, + "requires": { + "hoek": "2.x.x" + } + }, + "cryptiles": { + "version": "2.0.5", + "bundled": true, + "requires": { + "boom": "2.x.x" + } + }, + "hoek": { + "version": "2.16.3", + "bundled": true + }, + "sntp": { + "version": "1.0.9", + "bundled": true, + "requires": { + "hoek": "2.x.x" + } + } + } + }, + "http-signature": { + "version": "1.1.1", + "bundled": true, + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "dependencies": { + "assert-plus": { + "version": "0.2.0", + "bundled": true + }, + "jsprim": { + "version": "1.3.0", + "bundled": true, + "requires": { + "extsprintf": "1.0.2", + "json-schema": "0.2.2", + "verror": "1.3.6" + }, + "dependencies": { + "extsprintf": { + "version": "1.0.2", + "bundled": true + }, + "json-schema": { + "version": "0.2.2", + "bundled": true + }, + "verror": { + "version": "1.3.6", + "bundled": true, + "requires": { + "extsprintf": "1.0.2" + } + } + } + }, + "sshpk": { + "version": "1.9.2", + "bundled": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jodid25519": "^1.0.0", + "jsbn": "~0.1.0", + "tweetnacl": "~0.13.0" + }, + "dependencies": { + "asn1": { + "version": "0.2.3", + "bundled": true + }, + "assert-plus": { + "version": "1.0.0", + "bundled": true + }, + "dashdash": { + "version": "1.14.0", + "bundled": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "bundled": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "getpass": { + "version": "0.1.6", + "bundled": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "jodid25519": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "jsbn": { + "version": "0.1.0", + "bundled": true, + "optional": true + }, + "tweetnacl": { + "version": "0.13.3", + "bundled": true, + "optional": true + } + } + } + } + }, + "is-typedarray": { + "version": "1.0.0", + "bundled": true + }, + "isstream": { + "version": "0.1.2", + "bundled": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "bundled": true + }, + "mime-types": { + "version": "2.1.11", + "bundled": true, + "requires": { + "mime-db": "~1.23.0" + }, + "dependencies": { + "mime-db": { + "version": "1.23.0", + "bundled": true + } + } + }, + "node-uuid": { + "version": "1.4.7", + "bundled": true + }, + "oauth-sign": { + "version": "0.8.2", + "bundled": true + }, + "qs": { + "version": "6.2.1", + "bundled": true + }, + "stringstream": { + "version": "0.0.5", + "bundled": true + }, + "tough-cookie": { + "version": "2.3.1", + "bundled": true + }, + "tunnel-agent": { + "version": "0.4.3", + "bundled": true + } + } + }, + "retry": { + "version": "0.10.0", + "bundled": true + }, + "rimraf": { + "version": "2.5.4", + "bundled": true, + "requires": { + "glob": "^7.0.5" + } + }, + "semver": { + "version": "5.1.0", + "bundled": true + }, + "sha": { + "version": "2.0.1", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "readable-stream": { + "version": "2.0.2", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "process-nextick-args": "~1.0.0", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "bundled": true + }, + "isarray": { + "version": "0.0.1", + "bundled": true + }, + "process-nextick-args": { + "version": "1.0.3", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + }, + "util-deprecate": { + "version": "1.0.1", + "bundled": true + } + } + } + } + }, + "slide": { + "version": "1.1.6", + "bundled": true + }, + "sorted-object": { + "version": "2.0.0", + "bundled": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "bundled": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "tar": { + "version": "2.2.1", + "bundled": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true + }, + "umask": { + "version": "1.1.0", + "bundled": true + }, + "validate-npm-package-license": { + "version": "3.0.1", + "bundled": true, + "requires": { + "spdx-correct": "~1.0.0", + "spdx-expression-parse": "~1.0.0" + }, + "dependencies": { + "spdx-correct": { + "version": "1.0.2", + "bundled": true, + "requires": { + "spdx-license-ids": "^1.0.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.2", + "bundled": true, + "requires": { + "spdx-exceptions": "^1.0.4", + "spdx-license-ids": "^1.0.0" + }, + "dependencies": { + "spdx-exceptions": { + "version": "1.0.4", + "bundled": true + } + } + } + } + }, + "validate-npm-package-name": { + "version": "2.2.2", + "bundled": true, + "requires": { + "builtins": "0.0.7" + }, + "dependencies": { + "builtins": { + "version": "0.0.7", + "bundled": true + } + } + }, + "which": { + "version": "1.2.11", + "bundled": true, + "requires": { + "isexe": "^1.1.1" + }, + "dependencies": { + "isexe": { + "version": "1.1.2", + "bundled": true + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true + }, + "write-file-atomic": { + "version": "1.1.4", + "bundled": true, + "requires": { + "graceful-fs": "^4.1.2", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + } + } + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + } + } + }, + "q": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz", + "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "requires": { + "os-tmpdir": "~1.0.1" + } + } + } + }, + "gitbook-markdown": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/gitbook-markdown/-/gitbook-markdown-0.5.3.tgz", + "integrity": "sha1-pXUO8eSZ5T7ltixdRPxL1vukG8c=", + "requires": { + "kramed": "0.5.5", + "kramed-text-renderer": "0.2.1", + "lodash": "^3.2.0" + } + }, + "gitbook-parsers": { + "version": "0.8.9", + "resolved": "https://registry.npmjs.org/gitbook-parsers/-/gitbook-parsers-0.8.9.tgz", + "integrity": "sha1-mC97ysStqYo2jDAHu86FV9Y0jXk=", + "requires": { + "gitbook-asciidoc": "0.2.4", + "gitbook-markdown": "0.5.3", + "gitbook-restructuredtext": "0.2.3", + "lodash": "^3.2.0", + "q": "^1.1.2" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + } + } + }, + "gitbook-plugin-back-to-top-button": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/gitbook-plugin-back-to-top-button/-/gitbook-plugin-back-to-top-button-0.1.4.tgz", + "integrity": "sha1-5iGDOLDvGdWOb2YAmUNQt26ANd8=" + }, + "gitbook-plugin-edit-link": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/gitbook-plugin-edit-link/-/gitbook-plugin-edit-link-2.0.2.tgz", + "integrity": "sha1-2PzZJ+ztgeemYqctWdtgnq/X5y8=" + }, + "gitbook-plugin-fontsettings": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/gitbook-plugin-fontsettings/-/gitbook-plugin-fontsettings-1.0.2.tgz", + "integrity": "sha1-bNXbb7vHBszXhhVLqH3Whgb5fcg=" + }, + "gitbook-plugin-github": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-github/-/gitbook-plugin-github-2.0.0.tgz", + "integrity": "sha1-UWbnY8/MQC1DKIC3pshcHFS1ao0=" + }, + "gitbook-plugin-github-buttons": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-github-buttons/-/gitbook-plugin-github-buttons-2.1.0.tgz", + "integrity": "sha1-eZOqHmwgUeF0POTiw3PEPbZeiuQ=" + }, + "gitbook-plugin-highlight": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gitbook-plugin-highlight/-/gitbook-plugin-highlight-1.0.3.tgz", + "integrity": "sha1-9smqu/TXfjfD/pKXNHXVZBULgyE=", + "requires": { + "highlight.js": "8.8.0" + } + }, + "gitbook-plugin-livereload": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-livereload/-/gitbook-plugin-livereload-0.0.1.tgz", + "integrity": "sha1-wMncb1X4L8JPl1MrJSh6u7tBa5Y=" + }, + "gitbook-plugin-page-toc-button": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-page-toc-button/-/gitbook-plugin-page-toc-button-0.1.1.tgz", + "integrity": "sha1-KBoK3j8NiXtjqDpKPGPMhTpglvk=" + }, + "gitbook-plugin-prism": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-prism/-/gitbook-plugin-prism-2.4.0.tgz", + "integrity": "sha512-qt16TmNJA5SVpFF+4OhiaPf5VHg/aWj9QFuYEC/dUHmBgYbaq5HMwsqGFFXj4N/zwqAzr3YDiq1V/udsU5D1qA==", + "requires": { + "cheerio": "0.22.0", + "mkdirp": "0.5.1", + "prismjs": "^1.15.0" + }, + "dependencies": { + "cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=", + "requires": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + } + }, + "css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "requires": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "readable-stream": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "gitbook-plugin-search": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/gitbook-plugin-search/-/gitbook-plugin-search-1.1.0.tgz", + "integrity": "sha1-PTaSigUYiFybo4daqW5m/9lsTPc=", + "requires": { + "lodash": "3.10.1", + "lunr": "0.5.12" + } + }, + "gitbook-plugin-search-plus": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/gitbook-plugin-search-plus/-/gitbook-plugin-search-plus-0.0.11.tgz", + "integrity": "sha1-tddEREeU73GUr8OwsbJNwvQTatQ=", + "requires": { + "html-entities": "1.2.0" + } + }, + "gitbook-plugin-sharing": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-sharing/-/gitbook-plugin-sharing-1.0.1.tgz", + "integrity": "sha1-MjDRql8DOYID2lxHPh671HRxtxg=", + "requires": { + "lodash": "^3.10.1" + } + }, + "gitbook-plugin-sharing-plus": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/gitbook-plugin-sharing-plus/-/gitbook-plugin-sharing-plus-0.0.2.tgz", + "integrity": "sha1-FstYGACikvAbvY19Ic6jID0Jcz8=", + "requires": { + "lodash": "^3.10.1" + } + }, + "gitbook-plugin-splitter": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/gitbook-plugin-splitter/-/gitbook-plugin-splitter-0.0.8.tgz", + "integrity": "sha1-8rBRMGD8kma0awQYLk7KHUtx+vw=" + }, + "gitbook-plugin-tbfed-pagefooter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/gitbook-plugin-tbfed-pagefooter/-/gitbook-plugin-tbfed-pagefooter-0.0.1.tgz", + "integrity": "sha1-Fu54QGLdhQQmTEd+h2X8ScQb7T0=", + "requires": { + "moment": "^2.10.6" + } + }, + "gitbook-restructuredtext": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/gitbook-restructuredtext/-/gitbook-restructuredtext-0.2.3.tgz", + "integrity": "sha1-4tzIMEIrDJ06EDIfmAHWKCqeY7g=", + "requires": { + "cheerio": "^0.19.0", + "lodash": "^3.2.0", + "q": "^1.1.2", + "tmp": "0.0.24" + }, + "dependencies": { + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" + } + } + }, + "github-slugid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/github-slugid/-/github-slugid-1.0.0.tgz", + "integrity": "sha1-gL5yPR3uikqyN9wspzRT5wa7VVk=" + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "glob-parent": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-1.3.0.tgz", + "integrity": "sha1-lx7dgW7V21hwW1gHlkemTQrveWg=", + "requires": { + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, + "graceful-fs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.5.tgz", + "integrity": "sha1-SogEdL3rcW/jJ4zyl5Lew436xBg=" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "hawk": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", + "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", + "requires": { + "boom": "0.4.x", + "cryptiles": "0.2.x", + "hoek": "0.9.x", + "sntp": "0.2.x" + } + }, + "highlight.js": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-8.8.0.tgz", + "integrity": "sha1-SdXiGF9HFzH06/39l0ZunulidW8=" + }, + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=" + }, + "html-entities": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.0.tgz", + "integrity": "sha1-QZSMr4XOgv7Tbk5qDtNxpmZDeeI=" + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + }, + "dependencies": { + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=" + } + } + }, + "http-errors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.3.1.tgz", + "integrity": "sha1-GX4izevUGYWF6GlO9nhhl7ke2UI=", + "requires": { + "inherits": "~2.0.1", + "statuses": "1" + } + }, + "http-parser-js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", + "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==" + }, + "http-signature": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", + "requires": { + "asn1": "0.1.11", + "assert-plus": "^0.1.5", + "ctype": "0.5.3" + } + }, + "iconv-lite": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz", + "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI=" + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-1.1.3.tgz", + "integrity": "sha1-tMZLgwPTkRRJKkYNNkzPsNPAoEU=" + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + } + } + }, + "json-schema-defaults": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-schema-defaults/-/json-schema-defaults-0.1.1.tgz", + "integrity": "sha1-HGxhA8Q0m3G29Ko4LD3ZqhyLraM=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "optional": true + } + } + }, + "jsonschema": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.0.2.tgz", + "integrity": "sha1-KSu4/TYmZpGobE6xQf9QCtsPVg8=" + }, + "juice": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/juice/-/juice-1.5.0.tgz", + "integrity": "sha1-lilL0uBQF/YUTdpbF5G9BBth+6w=", + "requires": { + "batch": "0.5.2", + "cheerio": "0.19.0", + "commander": "2.3.0", + "cssom": "0.3.0", + "slick": "1.12.1", + "web-resource-inliner": "1.1.4" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "kramed": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/kramed/-/kramed-0.5.5.tgz", + "integrity": "sha1-qTMpap5S2xOGquV0WE6lNua19ts=" + }, + "kramed-text-renderer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/kramed-text-renderer/-/kramed-text-renderer-0.2.1.tgz", + "integrity": "sha1-q+vAfAQPr3lC3KZPTu4MmxReeVE=" + }, + "lazy-cache": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", + "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=" + }, + "livereload-js": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", + "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==" + }, + "lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" + }, + "lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" + }, + "lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU=" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" + }, + "lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=" + }, + "lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" + }, + "lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU=" + }, + "lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=" + }, + "longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "requires": { + "es5-ext": "~0.10.2" + } + }, + "lunr": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-0.5.12.tgz", + "integrity": "sha1-ova314AcvizLFpbaZ/H3eI+J4Mg=" + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "memoizee": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.3.10.tgz", + "integrity": "sha1-TsoNiu057J0Bf0xcLy9kMvQuXI8=", + "requires": { + "d": "~0.1.1", + "es5-ext": "~0.10.11", + "es6-weak-map": "~0.1.4", + "event-emitter": "~0.3.4", + "lru-queue": "0.1", + "next-tick": "~0.2.2", + "timers-ext": "0.1" + }, + "dependencies": { + "next-tick": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-0.2.2.tgz", + "integrity": "sha1-ddpKkn7liH45BliABltzNkE7MQ0=" + } + } + }, + "merge-defaults": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/merge-defaults/-/merge-defaults-0.2.1.tgz", + "integrity": "sha1-3UIkjrlrtqUVIXJDIccv+Vg93oA=", + "requires": { + "lodash": "~2.4.1" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=" + } + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "dependencies": { + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "mime-db": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz", + "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc=" + }, + "mime-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", + "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" + }, + "mimer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mimer/-/mimer-1.0.0.tgz", + "integrity": "sha512-4ZJvCzfcwsBgPbkKXUzGoVZMWjv8IDIygkGzVc7uUYhgnK0t2LmGxxjdgH1i+pn0/KQfB5F/VKUJlfyTSOFQjg==" + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-2.4.1.tgz", + "integrity": "sha1-AhLgO4reib7GpZ/HW8KqA/lPD1M=", + "requires": { + "abbrev": "~1.0.5", + "ansi": "~0.3.0", + "ansicolors": "~0.3.2", + "ansistyles": "~0.1.3", + "archy": "~1.0.0", + "async-some": "~1.0.1", + "block-stream": "0.0.7", + "char-spinner": "~1.0.1", + "child-process-close": "~0.1.1", + "chmodr": "~0.1.0", + "chownr": "0", + "cmd-shim": "~2.0.1", + "columnify": "~1.3.2", + "config-chain": "~1.1.8", + "dezalgo": "~1.0.1", + "editor": "~0.1.0", + "fs-vacuum": "~1.2.5", + "fs-write-stream-atomic": "~1.0.2", + "fstream": "~1.0.3", + "fstream-npm": "~1.0.1", + "github-url-from-git": "~1.4.0", + "github-url-from-username-repo": "~1.0.2", + "glob": "~4.3.5", + "graceful-fs": "~3.0.5", + "inflight": "~1.0.4", + "inherits": "~2.0.1", + "ini": "~1.3.2", + "init-package-json": "~1.2.0", + "lockfile": "~1.0.0", + "lru-cache": "~2.5.0", + "minimatch": "~2.0.1", + "mkdirp": "~0.5.0", + "node-gyp": "~1.0.2", + "nopt": "~3.0.1", + "normalize-git-url": "~1.0.0", + "normalize-package-data": "~1.0.3", + "npm-cache-filename": "~1.0.1", + "npm-install-checks": "~1.0.5", + "npm-package-arg": "~2.1.3", + "npm-registry-client": "~6.0.3", + "npm-user-validate": "~0.1.1", + "npmlog": "~0.1.1", + "once": "~1.3.1", + "opener": "~1.4.0", + "osenv": "~0.1.0", + "path-is-inside": "~1.0.0", + "read": "~1.0.4", + "read-installed": "~3.1.5", + "read-package-json": "~1.2.7", + "readable-stream": "~1.0.33", + "realize-package-specifier": "~1.3.0", + "request": "~2.51.0", + "retry": "~0.6.1", + "rimraf": "~2.2.8", + "semver": "~4.2.0", + "sha": "~1.3.0", + "slide": "~1.1.6", + "sorted-object": "~1.0.0", + "tar": "~1.0.3", + "text-table": "~0.2.0", + "uid-number": "0.0.6", + "umask": "~1.1.0", + "which": "~1.0.8", + "wrappy": "~1.0.1", + "write-file-atomic": "~1.1.0" + }, + "dependencies": { + "abbrev": { + "version": "1.0.5", + "bundled": true + }, + "ansi": { + "version": "0.3.0", + "bundled": true + }, + "ansicolors": { + "version": "0.3.2", + "bundled": true + }, + "ansistyles": { + "version": "0.1.3", + "bundled": true + }, + "archy": { + "version": "1.0.0", + "bundled": true + }, + "async-some": { + "version": "1.0.1", + "bundled": true, + "requires": { + "dezalgo": "^1.0.0" + } + }, + "block-stream": { + "version": "0.0.7", + "bundled": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "char-spinner": { + "version": "1.0.1", + "bundled": true + }, + "child-process-close": { + "version": "0.1.1", + "bundled": true + }, + "chmodr": { + "version": "0.1.0", + "bundled": true + }, + "chownr": { + "version": "0.0.1", + "bundled": true + }, + "cmd-shim": { + "version": "2.0.1", + "bundled": true, + "requires": { + "graceful-fs": ">3.0.1 <4.0.0-0", + "mkdirp": "~0.5.0" + } + }, + "columnify": { + "version": "1.3.2", + "bundled": true, + "requires": { + "strip-ansi": "^2.0.0", + "wcwidth": "^1.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "2.0.0", + "bundled": true, + "requires": { + "ansi-regex": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "1.1.0", + "bundled": true + } + } + }, + "wcwidth": { + "version": "1.0.0", + "bundled": true, + "requires": { + "defaults": "^1.0.0" + }, + "dependencies": { + "defaults": { + "version": "1.0.0", + "bundled": true, + "requires": { + "clone": "~0.1.5" + }, + "dependencies": { + "clone": { + "version": "0.1.19", + "bundled": true + } + } + } + } + } + } + }, + "config-chain": { + "version": "1.1.8", + "bundled": true, + "requires": { + "ini": "1", + "proto-list": "~1.2.1" + }, + "dependencies": { + "proto-list": { + "version": "1.2.3", + "bundled": true + } + } + }, + "dezalgo": { + "version": "1.0.1", + "bundled": true, + "requires": { + "asap": "^1.0.0", + "wrappy": "1" + }, + "dependencies": { + "asap": { + "version": "1.0.0", + "bundled": true + } + } + }, + "editor": { + "version": "0.1.0", + "bundled": true + }, + "fs-vacuum": { + "version": "1.2.5", + "bundled": true, + "requires": { + "graceful-fs": "^3.0.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.2.8" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.2", + "bundled": true, + "requires": { + "graceful-fs": "^3.0.2" + } + }, + "fstream": { + "version": "1.0.3", + "bundled": true, + "requires": { + "graceful-fs": "3", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "fstream-npm": { + "version": "1.0.1", + "bundled": true, + "requires": { + "fstream-ignore": "^1.0.0", + "inherits": "2" + }, + "dependencies": { + "fstream-ignore": { + "version": "1.0.2", + "bundled": true, + "requires": { + "fstream": "^1.0.0", + "inherits": "2", + "minimatch": "^2.0.1" + } + } + } + }, + "github-url-from-git": { + "version": "1.4.0", + "bundled": true + }, + "github-url-from-username-repo": { + "version": "1.0.2", + "bundled": true + }, + "glob": { + "version": "4.3.5", + "bundled": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + } + }, + "graceful-fs": { + "version": "3.0.5", + "bundled": true + }, + "inflight": { + "version": "1.0.4", + "bundled": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.1", + "bundled": true + }, + "ini": { + "version": "1.3.2", + "bundled": true + }, + "init-package-json": { + "version": "1.2.0", + "bundled": true, + "requires": { + "glob": "^4.0.2", + "promzard": "~0.2.0", + "read": "~1.0.1", + "read-package-json": "1", + "semver": "2.x || 3.x || 4" + }, + "dependencies": { + "promzard": { + "version": "0.2.2", + "bundled": true, + "requires": { + "read": "1" + } + } + } + }, + "lockfile": { + "version": "1.0.0", + "bundled": true + }, + "lru-cache": { + "version": "2.5.0", + "bundled": true + }, + "minimatch": { + "version": "2.0.1", + "bundled": true, + "requires": { + "brace-expansion": "^1.0.0" + }, + "dependencies": { + "brace-expansion": { + "version": "1.0.1", + "bundled": true, + "requires": { + "balanced-match": "^0.2.0", + "concat-map": "0.0.0" + }, + "dependencies": { + "balanced-match": { + "version": "0.2.0", + "bundled": true + }, + "concat-map": { + "version": "0.0.0", + "bundled": true + } + } + } + } + }, + "mkdirp": { + "version": "0.5.0", + "bundled": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true + } + } + }, + "node-gyp": { + "version": "1.0.2", + "bundled": true, + "requires": { + "fstream": "^1.0.0", + "glob": "3 || 4", + "graceful-fs": "3", + "minimatch": "1", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0", + "osenv": "0", + "request": "2", + "rimraf": "2", + "semver": "2.x || 3.x || 4", + "tar": "^1.0.0", + "which": "1" + }, + "dependencies": { + "minimatch": { + "version": "1.0.0", + "bundled": true, + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "dependencies": { + "sigmund": { + "version": "1.0.0", + "bundled": true + } + } + } + } + }, + "nopt": { + "version": "3.0.1", + "bundled": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-git-url": { + "version": "1.0.0", + "bundled": true + }, + "normalize-package-data": { + "version": "1.0.3", + "bundled": true, + "requires": { + "github-url-from-git": "^1.3.0", + "github-url-from-username-repo": "^1.0.0", + "semver": "2 || 3 || 4" + } + }, + "npm-cache-filename": { + "version": "1.0.1", + "bundled": true + }, + "npm-install-checks": { + "version": "1.0.5", + "bundled": true, + "requires": { + "npmlog": "0.1 || 1", + "semver": "^2.3.0 || 3.x || 4" + } + }, + "npm-package-arg": { + "version": "2.1.3", + "bundled": true, + "requires": { + "semver": "4" + } + }, + "npm-registry-client": { + "version": "6.0.3", + "bundled": true, + "requires": { + "chownr": "0", + "concat-stream": "^1.4.6", + "graceful-fs": "^3.0.0", + "mkdirp": "^0.5.0", + "normalize-package-data": "~1.0.1", + "npm-package-arg": "^3.0.0", + "npmlog": "^4.1.2", + "once": "^1.3.0", + "request": "^2.47.0", + "retry": "^0.6.1", + "rimraf": "2", + "semver": "2 >=2.2.1 || 3.x || 4", + "slide": "^1.1.3" + }, + "dependencies": { + "concat-stream": { + "version": "1.4.7", + "bundled": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~1.1.9", + "typedarray": "~0.0.5" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.13", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "bundled": true + }, + "isarray": { + "version": "0.0.1", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + } + } + }, + "typedarray": { + "version": "0.0.6", + "bundled": true + } + } + }, + "npm-package-arg": { + "version": "3.0.0", + "bundled": true, + "requires": { + "hosted-git-info": "^1.4.0", + "semver": "4" + }, + "dependencies": { + "hosted-git-info": { + "version": "1.5.3", + "bundled": true + } + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + } + } + }, + "npm-user-validate": { + "version": "0.1.1", + "bundled": true + }, + "npmlog": { + "version": "0.1.1", + "bundled": true, + "requires": { + "ansi": "~0.3.0" + } + }, + "once": { + "version": "1.3.1", + "bundled": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.4.0", + "bundled": true + }, + "osenv": { + "version": "0.1.0", + "bundled": true + }, + "path-is-inside": { + "version": "1.0.1", + "bundled": true + }, + "read": { + "version": "1.0.5", + "bundled": true, + "requires": { + "mute-stream": "~0.0.4" + }, + "dependencies": { + "mute-stream": { + "version": "0.0.4", + "bundled": true + } + } + }, + "read-installed": { + "version": "3.1.5", + "bundled": true, + "requires": { + "debuglog": "^1.0.1", + "graceful-fs": "2 || 3", + "read-package-json": "1", + "readdir-scoped-modules": "^1.0.0", + "semver": "2 || 3 || 4", + "slide": "~1.1.3", + "util-extend": "^1.0.1" + }, + "dependencies": { + "debuglog": { + "version": "1.0.1", + "bundled": true + }, + "readdir-scoped-modules": { + "version": "1.0.1", + "bundled": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^3.0.4", + "once": "^1.3.0" + } + }, + "util-extend": { + "version": "1.0.1", + "bundled": true + } + } + }, + "read-package-json": { + "version": "1.2.7", + "bundled": true, + "requires": { + "github-url-from-git": "^1.3.0", + "github-url-from-username-repo": "~1.0.0", + "glob": "^4.0.2", + "graceful-fs": "2 || 3", + "lru-cache": "2", + "normalize-package-data": "^1.0.0" + } + }, + "readable-stream": { + "version": "1.0.33", + "bundled": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "bundled": true + }, + "isarray": { + "version": "0.0.1", + "bundled": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true + } + } + }, + "realize-package-specifier": { + "version": "1.3.0", + "bundled": true, + "requires": { + "dezalgo": "^1.0.1", + "npm-package-arg": "^2.1.3" + } + }, + "request": { + "version": "2.51.0", + "bundled": true, + "requires": { + "aws-sign2": "~0.5.0", + "bl": "~0.9.0", + "caseless": "~0.8.0", + "combined-stream": "~0.0.5", + "forever-agent": "~0.5.0", + "form-data": "~0.2.0", + "hawk": "1.1.1", + "http-signature": "~0.10.0", + "json-stringify-safe": "~5.0.0", + "mime-types": "~1.0.1", + "node-uuid": "~1.4.0", + "oauth-sign": "~0.5.0", + "qs": "~2.3.1", + "stringstream": "~0.0.4", + "tough-cookie": ">=0.12.0", + "tunnel-agent": "~0.4.0" + }, + "dependencies": { + "aws-sign2": { + "version": "0.5.0", + "bundled": true + }, + "bl": { + "version": "0.9.3", + "bundled": true, + "requires": { + "readable-stream": "~1.0.26" + } + }, + "caseless": { + "version": "0.8.0", + "bundled": true + }, + "combined-stream": { + "version": "0.0.7", + "bundled": true, + "requires": { + "delayed-stream": "0.0.5" + }, + "dependencies": { + "delayed-stream": { + "version": "0.0.5", + "bundled": true + } + } + }, + "forever-agent": { + "version": "0.5.2", + "bundled": true + }, + "form-data": { + "version": "0.2.0", + "bundled": true, + "requires": { + "async": "~0.9.0", + "combined-stream": "~0.0.4", + "mime-types": "~2.0.3" + }, + "dependencies": { + "async": { + "version": "0.9.0", + "bundled": true + }, + "mime-types": { + "version": "2.0.4", + "bundled": true, + "requires": { + "mime-db": "~1.3.0" + }, + "dependencies": { + "mime-db": { + "version": "1.3.0", + "bundled": true + } + } + } + } + }, + "hawk": { + "version": "1.1.1", + "bundled": true, + "requires": { + "boom": "0.4.x", + "cryptiles": "0.2.x", + "hoek": "0.9.x", + "sntp": "0.2.x" + }, + "dependencies": { + "boom": { + "version": "0.4.2", + "bundled": true, + "requires": { + "hoek": "0.9.x" + } + }, + "cryptiles": { + "version": "0.2.2", + "bundled": true, + "requires": { + "boom": "0.4.x" + } + }, + "hoek": { + "version": "0.9.1", + "bundled": true + }, + "sntp": { + "version": "0.2.4", + "bundled": true, + "requires": { + "hoek": "0.9.x" + } + } + } + }, + "http-signature": { + "version": "0.10.0", + "bundled": true, + "requires": { + "asn1": "0.1.11", + "assert-plus": "0.1.2", + "ctype": "0.5.2" + }, + "dependencies": { + "asn1": { + "version": "0.1.11", + "bundled": true + }, + "assert-plus": { + "version": "0.1.2", + "bundled": true + }, + "ctype": { + "version": "0.5.2", + "bundled": true + } + } + }, + "json-stringify-safe": { + "version": "5.0.0", + "bundled": true + }, + "mime-types": { + "version": "1.0.2", + "bundled": true + }, + "node-uuid": { + "version": "1.4.2", + "bundled": true + }, + "oauth-sign": { + "version": "0.5.0", + "bundled": true + }, + "qs": { + "version": "2.3.3", + "bundled": true + }, + "stringstream": { + "version": "0.0.4", + "bundled": true + }, + "tough-cookie": { + "version": "0.12.1", + "bundled": true, + "requires": { + "punycode": ">=0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "bundled": true + } + } + }, + "tunnel-agent": { + "version": "0.4.0", + "bundled": true + } + } + }, + "retry": { + "version": "0.6.1", + "bundled": true + }, + "rimraf": { + "version": "2.2.8", + "bundled": true + }, + "semver": { + "version": "4.2.0", + "bundled": true + }, + "sha": { + "version": "1.3.0", + "bundled": true, + "requires": { + "graceful-fs": "2 || 3", + "readable-stream": "~1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.1.13", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "isarray": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "string_decoder": { + "version": "0.10.31", + "bundled": true, + "optional": true + } + } + } + } + }, + "slide": { + "version": "1.1.6", + "bundled": true + }, + "sorted-object": { + "version": "1.0.0", + "bundled": true + }, + "tar": { + "version": "1.0.3", + "bundled": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, + "text-table": { + "version": "0.2.0", + "bundled": true + }, + "uid-number": { + "version": "0.0.6", + "bundled": true + }, + "umask": { + "version": "1.1.0", + "bundled": true + }, + "which": { + "version": "1.0.8", + "bundled": true + }, + "wrappy": { + "version": "1.0.1", + "bundled": true + }, + "write-file-atomic": { + "version": "1.1.0", + "bundled": true, + "requires": { + "graceful-fs": "^3.0.2", + "slide": "^1.1.5" + } + } + } + }, + "npmi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/npmi/-/npmi-0.1.1.tgz", + "integrity": "sha1-ngEkkc7KSByKPz8SNblfJ1UlsHY=", + "requires": { + "npm": "^2.1.5", + "semver": "^4.1.0" + }, + "dependencies": { + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + } + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "nunjucks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-2.2.0.tgz", + "integrity": "sha1-rn93bmVht0uJyJf3NdSDRn/qveA=", + "requires": { + "asap": "^2.0.3", + "chokidar": "^1.0.0", + "optimist": "*" + } + }, + "nunjucks-autoescape": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nunjucks-autoescape/-/nunjucks-autoescape-1.0.0.tgz", + "integrity": "sha1-3SPDsbg6uegdMW9/CM9xiztzzX8=" + }, + "nunjucks-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nunjucks-filter/-/nunjucks-filter-1.0.0.tgz", + "integrity": "sha1-R5UybYkXtgBcNCoNkdQRDKvSSp4=" + }, + "oauth-sign": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.5.0.tgz", + "integrity": "sha1-12f1FpMlYg6rLgh+8MRy53PbZGE=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "opal-npm-wrapper": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/opal-npm-wrapper/-/opal-npm-wrapper-0.1.1.tgz", + "integrity": "sha1-nJTSC+Tkui3yqS2mu95vMhOsIJU=" + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "prismjs": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.16.0.tgz", + "integrity": "sha512-OA4MKxjFZHSvZcisLGe14THYsug/nF6O1f0pAJc0KN0wTyAcLqmsbE+lTGKSpyh+9pEW57+k6pg2AfYR+coyHA==", + "requires": { + "clipboard": "^2.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "psl": { + "version": "1.1.32", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", + "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "q": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz", + "integrity": "sha1-EYcq7t7okmgRCxCnGESP+xARKhQ=" + }, + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=" + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "raw-body": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.1.7.tgz", + "integrity": "sha1-rf6s4uT7MJgFgBTQjActzFl1h3Q=", + "requires": { + "bytes": "2.4.0", + "iconv-lite": "0.4.13", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" + } + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-1.4.0.tgz", + "integrity": "sha1-xd5vyz3sgFI8HHARPxoZDYr4LIk=", + "requires": { + "graceful-fs": "~4.1.2", + "minimatch": "~0.2.12", + "readable-stream": "~1.0.26-2" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "request": { + "version": "2.51.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.51.0.tgz", + "integrity": "sha1-NdALvswBLlX5B7G9ng29V3v+8m4=", + "requires": { + "aws-sign2": "~0.5.0", + "bl": "~0.9.0", + "caseless": "~0.8.0", + "combined-stream": "~0.0.5", + "forever-agent": "~0.5.0", + "form-data": "~0.2.0", + "hawk": "1.1.1", + "http-signature": "~0.10.0", + "json-stringify-safe": "~5.0.0", + "mime-types": "~1.0.1", + "node-uuid": "~1.4.0", + "oauth-sign": "~0.5.0", + "qs": "~2.3.1", + "stringstream": "~0.0.4", + "tough-cookie": ">=0.12.0", + "tunnel-agent": "~0.4.0" + } + }, + "resolve": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", + "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=" + }, + "right-align": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", + "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "requires": { + "align-text": "^0.1.1" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "optional": true + }, + "semver": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.1.tgz", + "integrity": "sha1-n7P0AE+QDYPEeWj+QvdYPgWDLMk=" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "slick": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.1.tgz", + "integrity": "sha1-IRIFGUDeKw0O8n9k8b5sMsZZy4c=" + }, + "sntp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", + "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", + "requires": { + "hoek": "0.9.x" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "spawn-cmd": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/spawn-cmd/-/spawn-cmd-0.0.2.tgz", + "integrity": "sha1-bV4lH60OqwCw8ZPSRWaaeiKOwN4=" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "templayed": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/templayed/-/templayed-0.2.3.tgz", + "integrity": "sha1-RwbfYlvGrs2Gt8n2sPtUi5XN92k=" + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "optional": true + }, + "tiny-lr": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.2.1.tgz", + "integrity": "sha1-s/26gC5dVqM8L28QeUsy5Hescp0=", + "requires": { + "body-parser": "~1.14.0", + "debug": "~2.2.0", + "faye-websocket": "~0.10.0", + "livereload-js": "^2.2.0", + "parseurl": "~1.3.0", + "qs": "~5.1.0" + }, + "dependencies": { + "debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", + "requires": { + "ms": "0.7.1" + } + }, + "ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=" + }, + "qs": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-5.1.0.tgz", + "integrity": "sha1-TZMuXH6kEcynajEtOaYGIA/VDNk=" + } + } + }, + "tmp": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", + "integrity": "sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=" + }, + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + } + } + }, + "uglify-js": { + "version": "2.8.29", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", + "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "requires": { + "source-map": "~0.5.1", + "uglify-to-browserify": "~1.0.0", + "yargs": "~3.10.0" + } + }, + "uglify-to-browserify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", + "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "optional": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "urijs": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.17.0.tgz", + "integrity": "sha1-IPzTK89g4OkAfCQVwsm4vcQ7M7E=" + }, + "user-home": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", + "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", + "requires": { + "os-homedir": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "web-resource-inliner": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-1.1.4.tgz", + "integrity": "sha1-E1dsJ6oUsHHY9qlRGykPsyV+VqQ=", + "requires": { + "async": "^0.9.0", + "clean-css": "1.1.7", + "cli-color": "^0.3.2", + "datauri": "~0.2.0", + "request": "^2.49.0", + "uglify-js": "^2.4.1", + "xtend": "^4.0.0" + } + }, + "websocket-driver": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", + "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "requires": { + "http-parser-js": ">=0.4.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", + "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=" + }, + "wordwrap": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", + "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xmlhttprequest": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.6.0.tgz", + "integrity": "sha1-ST0oX1kmb9y41P79JTRae2k8lmw=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "yargs": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", + "requires": { + "camelcase": "^1.0.2", + "cliui": "^2.1.0", + "decamelize": "^1.0.0", + "window-size": "0.1.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..63cbff2 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "scripts": { + "serve": "gitbook serve", + "build": "gitbook build" + }, + "dependencies": { + "gitbook": "^2.6.9", + "gitbook-cli": "^2.3.2", + "gitbook-plugin-back-to-top-button": "^0.1.4", + "gitbook-plugin-edit-link": "^2.0.2", + "gitbook-plugin-github": "^2.0.0", + "gitbook-plugin-github-buttons": "^2.1.0", + "gitbook-plugin-page-toc-button": "^0.1.1", + "gitbook-plugin-prism": "^2.4.0", + "gitbook-plugin-search-plus": "0.0.11", + "gitbook-plugin-sharing-plus": "0.0.2", + "gitbook-plugin-splitter": "0.0.8", + "gitbook-plugin-tbfed-pagefooter": "0.0.1" + } +} From cdd1e4c9e50a1711085218706d0532e3afd7e2a7 Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Wed, 5 Jun 2019 16:51:41 +0800 Subject: [PATCH 09/17] Fix style --- objects/set-object.md | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/objects/set-object.md b/objects/set-object.md index 2dc79a5..e981c39 100644 --- a/objects/set-object.md +++ b/objects/set-object.md @@ -1,13 +1,14 @@ -#### python集合 +# python集合 set是无序且不重复的集合,是可变的,通常用来从列表中删除重复项以及计算数学运算,如交集、并集、差分和对称差分等集合操作。set 支持 x in set, len(set),和 for x in set。作为一个无序的集合,set不记录元素位置或者插入点。因此,sets不支持 indexing, 或其它类序列的操作。 -#### python集合概述 +## python集合概述 在set中,对应的set的值的存储是通过结构setentry来保存数据值的; -``` +源文件:[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L26) +``` typedef struct { PyObject *key; Py_hash_t hash; /* Cached hash code of the key */ @@ -16,6 +17,8 @@ typedef struct { key就是保存的数据,hash就是保存的数据的hash,便于查找,set也是基于hash表来实现。对应的setentry所对应的set的数据结构如下; +源文件:[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42) + ``` typedef struct { @@ -48,7 +51,7 @@ typedef struct { ![内存图片](./python_set.png) -#### python集合(set)示例 +## python集合(set)示例 示例脚本如下: @@ -115,10 +118,12 @@ python -m dis set_test.py 通过该字节码指令可知,创建set调用了BUILD_SET指令,初始化完成之后,就调用set的add方法添加元素,调用remove删除元素,调用update来更新集合,通过union来合并集合。接下来就详细分析一下相关的操作流程。 -##### set的创建与初始化 +## set的创建与初始化 查找BUILD_SET的虚拟机执行函数如下; +源文件:[Python/ceval.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Python/ceval.c#L2318) + ``` // Python/ceval.c @@ -147,6 +152,8 @@ python -m dis set_test.py 此时继续查看PySet_New函数的执行流程; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286) + ``` PyObject * @@ -188,10 +195,12 @@ make_new_set(PyTypeObject *type, PyObject *iterable) 从PySet_New的执行流程可知,字典的初始化过程就是初始化相关数据结构。 -##### set的插入 +## set的插入 在本例的初始化过程中,由于传入了初始值1,2,所以会在执行字节码指令的时候,执行PySet_Add,该函数的本质与set_a.add(3)本质都调用了更底层set_add_key函数; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338) + ``` int @@ -208,6 +217,8 @@ PySet_Add(PyObject *anyset, PyObject *key) 继续查看set_add_key函数的执行过程; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419) + ``` static int set_add_key(PySetObject *so, PyObject *key) @@ -226,6 +237,8 @@ set_add_key(PySetObject *so, PyObject *key) 该函数主要就是检查传入的key是否能够被hash,如果能够被hash则直接返回,如果能被hash则继续调用set_add_entry函数将值加入到set中; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L136) + ``` static int @@ -375,10 +388,12 @@ s.add(7) // index = 9 & 7 = 1 大致的set的插入过程执行完毕。 -##### set的删除 +## set的删除 set的删除操作主要集中在set_remove()函数上,如下示例; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L1921) + ``` static PyObject * @@ -411,6 +426,8 @@ set_remove(PySetObject *so, PyObject *key) 此时就会调用set_discard_key方法来讲对应的entry设置为dummy;set_discard_key方法如下; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447) + ``` static int @@ -430,6 +447,8 @@ set_discard_key(PySetObject *so, PyObject *key) 该函数主要就是做了检查key是否可用hash的检查,此时如果可用hash则调用set_discard_entry方法; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L400) + ``` static int @@ -454,11 +473,12 @@ set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash) 此时就是查找该值,如果找到该值并将该值设置为dummy,并且将used值减1,此处没有减去fill的数量,从此处可知,fill包括所有曾经申请过的数量。 - -##### set的resize +## set的resize set的resize主要依靠set_table_reseize函数来实现; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L302) + ``` static int set_table_resize(PySetObject *so, Py_ssize_t minused) @@ -543,6 +563,8 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) 主要是检查是否table相同并且需要重新resize的值,然后判断是否fill与used相同,如果相同则全部插入,如果不同,则遍历旧table讲不为空并且不为dummy的值插入到新表中; +源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L267) + ``` static void set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash) From d8f4eb757c98fbeb68a83ec2d9641607504b31b1 Mon Sep 17 00:00:00 2001 From: ww <2768937530@qq.com> Date: Wed, 5 Jun 2019 17:05:54 +0800 Subject: [PATCH 10/17] Add source code line --- objects/set-object.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/objects/set-object.md b/objects/set-object.md index e981c39..cb1dc70 100644 --- a/objects/set-object.md +++ b/objects/set-object.md @@ -6,7 +6,7 @@ set是无序且不重复的集合,是可变的,通常用来从列表中删 在set中,对应的set的值的存储是通过结构setentry来保存数据值的; -源文件:[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L26) +`源文件:`[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L26) ``` typedef struct { @@ -17,7 +17,7 @@ typedef struct { key就是保存的数据,hash就是保存的数据的hash,便于查找,set也是基于hash表来实现。对应的setentry所对应的set的数据结构如下; -源文件:[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42) +`源文件:`[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42) ``` @@ -122,7 +122,7 @@ python -m dis set_test.py 查找BUILD_SET的虚拟机执行函数如下; -源文件:[Python/ceval.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Python/ceval.c#L2318) +`源文件:`[Python/ceval.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Python/ceval.c#L2318) ``` // Python/ceval.c @@ -152,7 +152,7 @@ python -m dis set_test.py 此时继续查看PySet_New函数的执行流程; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286) ``` @@ -199,7 +199,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable) 在本例的初始化过程中,由于传入了初始值1,2,所以会在执行字节码指令的时候,执行PySet_Add,该函数的本质与set_a.add(3)本质都调用了更底层set_add_key函数; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338) ``` @@ -217,7 +217,7 @@ PySet_Add(PyObject *anyset, PyObject *key) 继续查看set_add_key函数的执行过程; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419) ``` static int @@ -237,7 +237,7 @@ set_add_key(PySetObject *so, PyObject *key) 该函数主要就是检查传入的key是否能够被hash,如果能够被hash则直接返回,如果能被hash则继续调用set_add_entry函数将值加入到set中; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L136) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L136) ``` @@ -392,7 +392,7 @@ s.add(7) // index = 9 & 7 = 1 set的删除操作主要集中在set_remove()函数上,如下示例; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L1921) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L1921) ``` @@ -426,7 +426,7 @@ set_remove(PySetObject *so, PyObject *key) 此时就会调用set_discard_key方法来讲对应的entry设置为dummy;set_discard_key方法如下; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447) ``` @@ -447,7 +447,7 @@ set_discard_key(PySetObject *so, PyObject *key) 该函数主要就是做了检查key是否可用hash的检查,此时如果可用hash则调用set_discard_entry方法; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L400) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L400) ``` @@ -477,7 +477,7 @@ set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash) set的resize主要依靠set_table_reseize函数来实现; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L302) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L302) ``` static int @@ -563,7 +563,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) 主要是检查是否table相同并且需要重新resize的值,然后判断是否fill与used相同,如果相同则全部插入,如果不同,则遍历旧table讲不为空并且不为dummy的值插入到新表中; -源文件:[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L267) +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L267) ``` static void From 3ed8f75fa27c835a54d13a231ef5cd57bb9db072 Mon Sep 17 00:00:00 2001 From: istommao Date: Sat, 8 Jun 2019 14:22:16 +0800 Subject: [PATCH 11/17] =?UTF-8?q?=E5=AE=8C=E5=96=84PyListObject=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- objects/PyListStructure.png | Bin 0 -> 11631 bytes objects/list-object.md | 413 ++++++++++++++++++++++++++++++++++++ 2 files changed, 413 insertions(+) create mode 100644 objects/PyListStructure.png diff --git a/objects/PyListStructure.png b/objects/PyListStructure.png new file mode 100644 index 0000000000000000000000000000000000000000..9e357bdc3bedbfe62c63e7fec76a4681cb40b0a7 GIT binary patch literal 11631 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 literal 0 HcmV?d00001 diff --git a/objects/list-object.md b/objects/list-object.md index 779bf7e..76b6fb2 100644 --- a/objects/list-object.md +++ b/objects/list-object.md @@ -1 +1,414 @@ # Python List 对象 + +在Python中的list可以存放任何类型的数据,查看`PyListObject`可以发现,list实际存放的是PyObject* 指针 + +## PyListObject + +`源文件:`[Include/listobject.h](https://github.com/python/cpython/blob/v3.7.0/Include/listobject.h#L23) + +```c +// listobject.h + +typedef struct { + PyObject_VAR_HEAD + /* Vector of pointers to list elements. list[0] is ob_item[0], etc. */ + PyObject **ob_item; + + /* ob_item contains space for 'allocated' elements. The number + * currently in use is ob_size. + * Invariants: + * 0 <= ob_size <= allocated + * len(list) == ob_size + * ob_item == NULL implies ob_size == allocated == 0 + * list.sort() temporarily sets allocated to -1 to detect mutations. + * + * Items must normally not be NULL, except during construction when + * the list is not yet visible outside the function that builds it. + */ + + // 可容纳元素的总数 + Py_ssize_t allocated; +} PyListObject; +``` + +示例 +```python +lst = [] +lst.append(1) +``` + +其存储结构如下图 + +![PyList structure](PyListStructure.png) + + + +## PyListObject对象的一些操作 + +- 创建PyListObject PyList_New +- 对象赋值 PyList_SetItem +- 获取元素 PyList_GetItem +- 插入元素 PyList_Insert +- 追加元素 PyList_Append +- 移除元素 list_remove +- 调整list大小 list_resize + +### PyList_New 创建对象 + +为了避免频繁的申请内存空间,创建PyListObject的时候会先检查缓冲池是否有可用空间 + +`源文件:`[Objects/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L136) + +```c +// listobject.c + +PyObject * +PyList_New(Py_ssize_t size) +{ + PyListObject *op; +#ifdef SHOW_ALLOC_COUNT + static int initialized = 0; + if (!initialized) { + Py_AtExit(show_alloc); + initialized = 1; + } +#endif + + // size 合法性检查 + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } + + // PyListObject对象缓冲池是否有可用空间 + if (numfree) { + numfree--; + op = free_list[numfree]; + _Py_NewReference((PyObject *)op); +#ifdef SHOW_ALLOC_COUNT + count_reuse++; +#endif + } else { + // 缓冲池满只能向系统申请内存 + op = PyObject_GC_New(PyListObject, &PyList_Type); + if (op == NULL) + return NULL; +#ifdef SHOW_ALLOC_COUNT + count_alloc++; +#endif + } + if (size <= 0) + op->ob_item = NULL; + else { + op->ob_item = (PyObject **) PyMem_Calloc(size, sizeof(PyObject *)); + if (op->ob_item == NULL) { + Py_DECREF(op); + return PyErr_NoMemory(); + } + } + Py_SIZE(op) = size; + op->allocated = size; + _PyObject_GC_TRACK(op); + return (PyObject *) op; +} +``` + +PyListObject缓冲池默认大小为80 `源文件:`[Include/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L101) + +```c +// listobject.c + +/* Empty list reuse scheme to save calls to malloc and free */ +#ifndef PyList_MAXFREELIST +#define PyList_MAXFREELIST 80 +#endif +static PyListObject *free_list[PyList_MAXFREELIST]; +static int numfree = 0; +``` + +### PyList_SetItem 元素赋值 + +`源文件:`[Objects/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L215) + +```c +// listobject.c + +int +PyList_SetItem(PyObject *op, Py_ssize_t i, + PyObject *newitem) +{ + PyObject **p; + if (!PyList_Check(op)) { + Py_XDECREF(newitem); + PyErr_BadInternalCall(); + return -1; + } + if (i < 0 || i >= Py_SIZE(op)) { + Py_XDECREF(newitem); + PyErr_SetString(PyExc_IndexError, + "list assignment index out of range"); + return -1; + } + p = ((PyListObject *)op) -> ob_item + i; + Py_XSETREF(*p, newitem); + return 0; +} +``` + +元素赋值的示例 + +```python +lst = [0, 1, 2] +lst[0] = 3 +# 这里 lst[0] = 3 会调用 PyList_SetItem 函数 +``` + + +### PyList_GetItem 获取元素 + +`源文件:`[Objects/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L195) + +```c +// Objects/listobject.c + +PyObject * +PyList_GetItem(PyObject *op, Py_ssize_t i) +{ + if (!PyList_Check(op)) { + PyErr_BadInternalCall(); + return NULL; + } + if (i < 0 || i >= Py_SIZE(op)) { + if (indexerr == NULL) { + indexerr = PyUnicode_FromString( + "list index out of range"); + if (indexerr == NULL) + return NULL; + } + PyErr_SetObject(PyExc_IndexError, indexerr); + return NULL; + } + return ((PyListObject *)op) -> ob_item[i]; +} +``` + +获取元素的示例 + +```python +lst = [1, 2, 3, 4] +print(lst[3]) +# lst[3] 实际调用的就是 PyList_GetItem +# 根据索引返回对应的元素 +``` + + +### PyList_Append 追加元素 + +PyList_Append 调用 app1 + +```c +int +PyList_Append(PyObject *op, PyObject *newitem) +{ + if (PyList_Check(op) && (newitem != NULL)) + return app1((PyListObject *)op, newitem); + PyErr_BadInternalCall(); + return -1; +} +``` + +`源文件:`[Objects/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L279) + +```c +// Objects/listobject.c + +static int +app1(PyListObject *self, PyObject *v) +{ + Py_ssize_t n = PyList_GET_SIZE(self); + + assert (v != NULL); + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot add more objects to list"); + return -1; + } + + if (list_resize(self, n+1) < 0) + return -1; + + Py_INCREF(v); + PyList_SET_ITEM(self, n, v); + return 0; +} +``` + +从`app1`代码可以看出追加元素操作大致流程如下 +- 调用list_resize,将list大小加一 +- 将元素插入list尾部 + +### PyList_Insert 插入元素 + +PyList_Insert 调用 ins1 + +```c +int +PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem) +{ + if (!PyList_Check(op)) { + PyErr_BadInternalCall(); + return -1; + } + return ins1((PyListObject *)op, where, newitem); +} +``` + +`源文件:`[Objects/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L236) + +```c +// Objects/listobject.c + +static int +ins1(PyListObject *self, Py_ssize_t where, PyObject *v) +{ + Py_ssize_t i, n = Py_SIZE(self); + PyObject **items; + if (v == NULL) { + PyErr_BadInternalCall(); + return -1; + } + if (n == PY_SSIZE_T_MAX) { + PyErr_SetString(PyExc_OverflowError, + "cannot add more objects to list"); + return -1; + } + + if (list_resize(self, n+1) < 0) + return -1; + + if (where < 0) { + where += n; + if (where < 0) + where = 0; + } + if (where > n) + where = n; + items = self->ob_item; + for (i = n; --i >= where; ) + items[i+1] = items[i]; + Py_INCREF(v); + items[where] = v; + return 0; +} +``` + +从`ins1`代码可以看出插入元素操作大致流程如下 +- 调用list_resize,将list大小加一 +- 将要插入的位置的元素都往后移一个位置 +- 将元素插入指定位置 + +### list_remove 移除元素 + +`源文件:`[Objects/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L2546) + +```c +// listobject.c + +static PyObject * +list_remove(PyListObject *self, PyObject *value) +/*[clinic end generated code: output=f087e1951a5e30d1 input=2dc2ba5bb2fb1f82]*/ +{ + Py_ssize_t i; + + for (i = 0; i < Py_SIZE(self); i++) { + int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ); + if (cmp > 0) { + if (list_ass_slice(self, i, i+1, + (PyObject *)NULL) == 0) + Py_RETURN_NONE; + return NULL; + } + else if (cmp < 0) + return NULL; + } + PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list"); + return NULL; +} +``` + +移除元素示例 + +```python +lst = [0, 2, 4, 3] +lst.remove(3) +""" +lst.remove(3) 会调用 list_remove函数, +list_remove函数会遍历列表,使用PyObject_RichCompareBool与目标值进行比较, +相同则调用list_ass_slice进行移除,当遍历完列表还未找到则报错 +""" +``` + +### list_resize 调整list存储空间 + +随着list元素的增加,list的存储空间可能会不够用,这个时候就需要扩大list的存储空间。 +随着list元素的减少,list的存储空间可能存在冗余,这个时候就需要缩小list的存储空间。 +函数`list_resize`就是用于调节list存储空间大小的 + +`源文件:`[Objects/listobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/listobject.c#L19) + +```c +// listobject.c + +static int +list_resize(PyListObject *self, Py_ssize_t newsize) +{ + PyObject **items; + size_t new_allocated, num_allocated_bytes; + Py_ssize_t allocated = self->allocated; + + /* Bypass realloc() when a previous overallocation is large enough + to accommodate the newsize. If the newsize falls lower than half + the allocated size, then proceed with the realloc() to shrink the list. + */ + if (allocated >= newsize && newsize >= (allocated >> 1)) { + assert(self->ob_item != NULL || newsize == 0); + Py_SIZE(self) = newsize; + return 0; + } + + /* This over-allocates proportional to the list size, making room + * for additional growth. The over-allocation is mild, but is + * enough to give linear-time amortized behavior over a long + * sequence of appends() in the presence of a poorly-performing + * system realloc(). + * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... + * Note: new_allocated won't overflow because the largest possible value + * is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t. + */ + new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6); + if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) { + PyErr_NoMemory(); + return -1; + } + + if (newsize == 0) + new_allocated = 0; + num_allocated_bytes = new_allocated * sizeof(PyObject *); + items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes); + if (items == NULL) { + PyErr_NoMemory(); + return -1; + } + self->ob_item = items; + Py_SIZE(self) = newsize; + self->allocated = new_allocated; + return 0; +} +``` + +当 `allocated/2 <= newsize <= allocated` 时,list_resize只会改变 ob_size不会改变allocated。 +其他情况则需要调用`PyMem_Realloc`函数分配新的空间存储列表元素。 + +列表allocated的增长模式是 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... + +其公式为 `new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6)` From 0aefa170bb39d05f15cca05bb427c81f1fd37330 Mon Sep 17 00:00:00 2001 From: istommao Date: Sat, 8 Jun 2019 14:24:43 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E4=BF=AE=E6=94=B9set-object=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=9D=97=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- objects/set-object.md | 92 +++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/objects/set-object.md b/objects/set-object.md index cb1dc70..d34f01b 100644 --- a/objects/set-object.md +++ b/objects/set-object.md @@ -8,7 +8,7 @@ set是无序且不重复的集合,是可变的,通常用来从列表中删 `源文件:`[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L26) -``` +```c typedef struct { PyObject *key; Py_hash_t hash; /* Cached hash code of the key */ @@ -19,8 +19,7 @@ key就是保存的数据,hash就是保存的数据的hash,便于查找,set `源文件:`[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42) -``` - +```c typedef struct { PyObject_HEAD @@ -39,7 +38,7 @@ typedef struct { * runtime null-tests. */ setentry *table; // 保存数据的数组数组指针 - Py_hash_t hash; /* Only used by frozenset objects */ + Py_hash_t hash; /* Only used by frozenset objects */ Py_ssize_t finger; /* Search finger for pop() */ setentry smalltable[PySet_MINSIZE]; // 保存数据的数组 默认初始化为8个元素,通过table指向 @@ -55,14 +54,13 @@ typedef struct { 示例脚本如下: -``` +```python set_a = {1,2}  set_a.add(3) set_a.add(4) set_a.remove(1) set_a.update({3,}) set_a.union({1,5}) - ``` 通过python反汇编获取该脚本的字节码; @@ -73,7 +71,7 @@ python -m dis set_test.py 输出的字节码如下所示; -``` +```shell 1 0 LOAD_CONST 0 (1) 3 LOAD_CONST 1 (2) 6 BUILD_SET 2 @@ -83,26 +81,26 @@ python -m dis set_test.py 15 LOAD_ATTR 1 (add) 18 LOAD_CONST 2 (3) 21 CALL_FUNCTION 1 - 24 POP_TOP + 24 POP_TOP 3 25 LOAD_NAME 0 (set_a) 28 LOAD_ATTR 1 (add) 31 LOAD_CONST 3 (4) 34 CALL_FUNCTION 1 - 37 POP_TOP + 37 POP_TOP 4 38 LOAD_NAME 0 (set_a) 41 LOAD_ATTR 2 (remove) 44 LOAD_CONST 0 (1) 47 CALL_FUNCTION 1 - 50 POP_TOP + 50 POP_TOP 5 51 LOAD_NAME 0 (set_a) 54 LOAD_ATTR 3 (update) 57 LOAD_CONST 2 (3) 60 BUILD_SET 1 63 CALL_FUNCTION 1 - 66 POP_TOP + 66 POP_TOP 6 67 LOAD_NAME 0 (set_a) 70 LOAD_ATTR 4 (union) @@ -110,7 +108,7 @@ python -m dis set_test.py 76 LOAD_CONST 4 (5) 79 BUILD_SET 2 82 CALL_FUNCTION 1 - 85 POP_TOP + 85 POP_TOP 86 LOAD_CONST 5 (None) 89 RETURN_VALUE ``` @@ -124,29 +122,29 @@ python -m dis set_test.py `源文件:`[Python/ceval.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Python/ceval.c#L2318) -``` +```c // Python/ceval.c - TARGET(BUILD_SET) { - PyObject *set = PySet_New(NULL); // 新建并初始化一个set - int err = 0; - int i; - if (set == NULL) - goto error; - for (i = oparg; i > 0; i--) { // 将传入初始化的参数传入 - PyObject *item = PEEK(i); - if (err == 0) - err = PySet_Add(set, item); // 并依次对set进行添加操作 - Py_DECREF(item); - } - STACKADJ(-oparg);                // 移动弹栈 - if (err != 0) { - Py_DECREF(set); - goto error; - } - PUSH(set);                     // 讲set压栈 - DISPATCH();                    // 执行下一条指令 + TARGET(BUILD_SET) { + PyObject *set = PySet_New(NULL); // 新建并初始化一个set + int err = 0; + int i; + if (set == NULL) + goto error; + for (i = oparg; i > 0; i--) { // 将传入初始化的参数传入 + PyObject *item = PEEK(i); + if (err == 0) + err = PySet_Add(set, item); // 并依次对set进行添加操作 + Py_DECREF(item); } + STACKADJ(-oparg);                // 移动弹栈 + if (err != 0) { + Py_DECREF(set); + goto error; + } + PUSH(set);                     // 讲set压栈 + DISPATCH();                    // 执行下一条指令 + } ``` @@ -155,7 +153,7 @@ python -m dis set_test.py `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286) -``` +```c PyObject * PySet_New(PyObject *iterable) { @@ -201,7 +199,7 @@ make_new_set(PyTypeObject *type, PyObject *iterable) `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338) -``` +```c int PySet_Add(PyObject *anyset, PyObject *key) @@ -219,7 +217,7 @@ PySet_Add(PyObject *anyset, PyObject *key) `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419) -``` +```c static int set_add_key(PySetObject *so, PyObject *key) { @@ -239,7 +237,7 @@ set_add_key(PySetObject *so, PyObject *key) `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L136) -``` +```c static int set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) @@ -301,7 +299,7 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) if (i + LINEAR_PROBES <= mask) {               // 检查当前索引值加上 9小于当前mask for (j = 0 ; j < LINEAR_PROBES ; j++) { // 循环9次 entry++;     // 向下一个位置 - if (entry->hash == 0 && entry->key == NULL)              // 如果找到当前hash为空或者key为空的则跳转到found_unused_or_dummy处执行 + if (entry->hash == 0 && entry->key == NULL)              // 如果找到当前hash为空或者key为空的则跳转到found_unused_or_dummy处执行 goto found_unused_or_dummy; if (entry->hash == hash) {   // 如果找到的hash值相同 PyObject *startkey = entry->key; // 获取该值 @@ -368,19 +366,19 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) 插入的概述如下,默认s初始化为空; -``` +```python s.add(1) // index = 1 & 7 = 1 ``` ![插入1](./set_insert_one.png) -``` +```python s.add(2) // index = 2 & 7 = 2 ``` ![插入2](./set_insert_two.png) -``` +```python s.add(7) // index = 9 & 7 = 1 ``` @@ -394,7 +392,7 @@ set的删除操作主要集中在set_remove()函数上,如下示例; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L1921) -``` +```c static PyObject * set_remove(PySetObject *so, PyObject *key) @@ -428,7 +426,7 @@ set_remove(PySetObject *so, PyObject *key) `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447) -``` +```c static int set_discard_key(PySetObject *so, PyObject *key) @@ -449,7 +447,7 @@ set_discard_key(PySetObject *so, PyObject *key) `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L400) -``` +```c static int set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash) @@ -479,7 +477,7 @@ set的resize主要依靠set_table_reseize函数来实现; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L302) -``` +```c static int set_table_resize(PySetObject *so, Py_ssize_t minused) { @@ -501,7 +499,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) /* Get space for a new table. */ oldtable = so->table;                   // 先获取旧的table assert(oldtable != NULL); - is_oldtable_malloced = oldtable != so->smalltable; + is_oldtable_malloced = oldtable != so->smalltable; if (newsize == PySet_MINSIZE) {                  // 如果获取的新大小与PySet_MINSIZE的大小相同 /* A large table is shrinking, or we can't get any smaller. */ @@ -565,7 +563,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L267) -``` +```c static void set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash) { @@ -577,7 +575,7 @@ set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash) while (1) { entry = &table[i]; // 获取当前entry if (entry->key == NULL) // 如果为空则跳转值found_null设置key与hash - goto found_null; + goto found_null; if (i + LINEAR_PROBES <= mask) { // 如果没有找到空值则通过该索引偏移9位去查找空余位置 for (j = 0; j < LINEAR_PROBES; j++) { entry++; From d73111325c6ede9a95cbadf0b2b80506618a1ff5 Mon Sep 17 00:00:00 2001 From: istommao Date: Sat, 8 Jun 2019 14:26:14 +0800 Subject: [PATCH 13/17] close #7 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4ece431..10139bb 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,9 @@ gitbook serve - [x] 修改 Python 源码 - [ ] Python 内建对象 - [x] Python 对象初探 - - [ ] Python 整数对象 + - [x] Python 整数对象 - [ ] Python 字符串 对象 - - [ ] Python List 对象 + - [x] Python List 对象 - [x] Python Dict 对象 - [x] Python Set 对象 - [ ] 实现简版 Python From f52b6cf02e1f3bc3b4665c6e9349a689e989d80d Mon Sep 17 00:00:00 2001 From: Prodesire Date: Sun, 16 Jun 2019 19:31:03 +0800 Subject: [PATCH 14/17] restructure --- SUMMARY.md | 22 ++-- book.json | 9 +- .../dict-mem.png} | Bin .../{dict-object.md => dict-object/index.md} | 108 +++++++++--------- objects/{ => list-object}/PyListStructure.png | Bin .../{list-object.md => list-object/index.md} | 0 .../{long-object.md => long-object/index.md} | 37 +++--- .../long-storage.png} | Bin .../long-x-add.png} | Bin .../long-x-sub.png} | Bin objects/{ => object}/PyObject.jpg | Bin objects/{ => object}/PyVarObject.jpg | Bin objects/{object.md => object/index.md} | 55 +++++---- .../object-category.jpg} | Bin .../object-runtime-relation.jpg} | Bin .../{set-object.md => set-object/index.md} | 71 ++++++------ .../set-insert-nine.png} | Bin .../set-insert-one.png} | Bin .../set-insert-two.png} | Bin .../{python_set.png => set-object/set.png} | Bin .../index.md} | 0 .../index.md} | 0 .../index.md} | 0 .../{modify-code.md => modify-code/index.md} | 0 .../index.md} | 0 preface/{ => windows-build}/build-files.png | Bin .../index.md} | 0 preface/{ => windows-build}/vs2017-build.png | Bin .../{ => windows-build}/vs2017-configure.png | Bin .../vs2017-installation.png | Bin .../{ => windows-build}/vs2017-properties.png | Bin 31 files changed, 144 insertions(+), 158 deletions(-) rename objects/{python_dict_mem.png => dict-object/dict-mem.png} (100%) rename objects/{dict-object.md => dict-object/index.md} (79%) rename objects/{ => list-object}/PyListStructure.png (100%) rename objects/{list-object.md => list-object/index.md} (100%) rename objects/{long-object.md => long-object/index.md} (93%) rename objects/{longobject_storage.png => long-object/long-storage.png} (100%) rename objects/{longobject_x_add.png => long-object/long-x-add.png} (100%) rename objects/{longobject_x_sub.png => long-object/long-x-sub.png} (100%) rename objects/{ => object}/PyObject.jpg (100%) rename objects/{ => object}/PyVarObject.jpg (100%) rename objects/{object.md => object/index.md} (84%) rename objects/{object_category.jpg => object/object-category.jpg} (100%) rename objects/{object_runtime_relation.jpg => object/object-runtime-relation.jpg} (100%) rename objects/{set-object.md => set-object/index.md} (87%) rename objects/{set_insert_nine.png => set-object/set-insert-nine.png} (100%) rename objects/{set_insert_one.png => set-object/set-insert-one.png} (100%) rename objects/{set_insert_two.png => set-object/set-insert-two.png} (100%) rename objects/{python_set.png => set-object/set.png} (100%) rename objects/{string-object.md => simple-interpreter/index.md} (100%) rename objects/{simple-implementation.md => str-object/index.md} (100%) rename preface/{code-organization.md => code-organization/index.md} (100%) rename preface/{modify-code.md => modify-code/index.md} (100%) rename preface/{unix-linux-build.md => unix-linux-build/index.md} (100%) rename preface/{ => windows-build}/build-files.png (100%) rename preface/{windows-build.md => windows-build/index.md} (100%) rename preface/{ => windows-build}/vs2017-build.png (100%) rename preface/{ => windows-build}/vs2017-configure.png (100%) rename preface/{ => windows-build}/vs2017-installation.png (100%) rename preface/{ => windows-build}/vs2017-properties.png (100%) diff --git a/SUMMARY.md b/SUMMARY.md index 4f20991..34ce3ec 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -3,19 +3,19 @@ ## 第 1 部分:序章 - [前言](README.md) -- [Python 源代码的组织](preface/code-organization.md) -- [Windows 环境下编译 Python](preface/windows-build.md) -- [UNIX/Linux 环境下编译 Python](preface/unix-linux-build.md) -- [修改 Python 源码](preface/modify-code.md) +- [Python 源代码的组织](preface/code-organization/index.md) +- [Windows 环境下编译 Python](preface/windows-build/index.md) +- [UNIX/Linux 环境下编译 Python](preface/unix-linux-build/index.md) +- [修改 Python 源码](preface/modify-code/index.md) ## 第 2 部分:Python 内建对象 -- [Python 对象初探](objects/object.md) -- [Python 整数对象](objects/long-object.md) -- [Python 字符串 对象](objects/string-object.md) -- [Python List 对象](objects/list-object.md) -- [Python Dict 对象](objects/dict-object.md) -- [Python Set 对象](objects/set-object.md) -- [实现简版 Python](objects/simple-implementation.md) +- [Python 对象初探](objects/object/index.md) +- [Python 整数对象](objects/long-object/index.md) +- [Python 字符串 对象](objects/string-object/index.md) +- [Python List 对象](objects/list-object/index.md) +- [Python Dict 对象](objects/dict-object/index.md) +- [Python Set 对象](objects/set-object/index.md) +- [实现简版 Python](objects/simple-interpreter/index.md) ## 第 3 部分:Python 虚拟机 diff --git a/book.json b/book.json index 4ad9ba9..d11f4a2 100644 --- a/book.json +++ b/book.json @@ -51,13 +51,12 @@ "all": ["weibo", "douban", "linkedin", "facebook", "google", "twitter"] }, "tbfed-pagefooter": { - "copyright": "Copyright © Prodesire 2018", + "copyright": "Copyright © FlagGo 2019", "modify_label": "该文件修订时间:", "modify_format": "YYYY-MM-DD HH:mm:ss" }, "edit-link": { - "base": - "https://github.com/flaggo/python3-source-code-analysis/edit/master", + "base": "https://github.com/flaggo/python3-source-code-analysis/edit/master", "label": "编辑此页面" }, "anchor-navigation-ex": { @@ -71,9 +70,7 @@ "console": "bash", "shell": "bash" }, - "css": [ - "prismjs/themes/prism-okaidia.css" - ] + "css": ["prismjs/themes/prism-okaidia.css"] } } } diff --git a/objects/python_dict_mem.png b/objects/dict-object/dict-mem.png similarity index 100% rename from objects/python_dict_mem.png rename to objects/dict-object/dict-mem.png diff --git a/objects/dict-object.md b/objects/dict-object/index.md similarity index 79% rename from objects/dict-object.md rename to objects/dict-object/index.md index f1912d3..fd6fac1 100644 --- a/objects/dict-object.md +++ b/objects/dict-object/index.md @@ -1,9 +1,10 @@ -# Python字典 +# Python 字典 -Dictionary object implementation using a hash table ,通过描述可知,python的字典就是实现了一个hash表。 +Dictionary object implementation using a hash table ,通过描述可知,python 的字典就是实现了一个 hash 表。 -## Python字典概述 -在python的字典中,一个键值对的对应保存就是PyDictEntry类型来保存; +## Python 字典概述 + +在 python 的字典中,一个键值对的对应保存就是 PyDictEntry 类型来保存; `源文件:`[Include/dict-common.h](https://github.com/python/cpython/blob/v3.7.0/Objects/dict-common.h#L1) @@ -17,31 +18,29 @@ typedef struct { } PyDictKeyEntry;  ``` -其中,me_hash就是哈希生成的值,me_key就是对应的key值,me_value就是对应的值。 -在python中,在一个PyDictObject对象的变化过程中,entry的状态会在不同的状态间转换。基本上在如下四种状态中转换:Unused、Active、Dummy和Pending。 +其中,me_hash 就是哈希生成的值,me_key 就是对应的 key 值,me_value 就是对应的值。 +在 python 中,在一个 PyDictObject 对象的变化过程中,entry 的状态会在不同的状态间转换。基本上在如下四种状态中转换:Unused、Active、Dummy 和 Pending。 -1. Unused:没有插入任何一个获取的key与value,并且在次之前也没有存储任何的key,value,每一个entry在初始化的时候都会处于这种状态,并且Unused会被里面切换到Active态,当有key插入,这是就是entry初始化的状态。 -2. Active:当index>=0时,me_key不为空并且me_value不为空,保存了一个键值对,Active可以转变为Dummy或者Pending状态,当一个健被删除的时候,这只会在me_value不为空的时候出现。 -3. Dummy:先前保存了一个Active的键值对,但是这个键值对被删除了并且一个活跃的键值对还没有填入该位置,Dummy可以转变为Active当删除的时候,Dummy的位置不能被重新使用,一旦发生碰撞,探针序列就无法知道这对键值对曾是活跃的键值对。 +1. Unused:没有插入任何一个获取的 key 与 value,并且在次之前也没有存储任何的 key,value,每一个 entry 在初始化的时候都会处于这种状态,并且 Unused 会被里面切换到 Active 态,当有 key 插入,这是就是 entry 初始化的状态。 +2. Active:当 index>=0 时,me_key 不为空并且 me_value 不为空,保存了一个键值对,Active 可以转变为 Dummy 或者 Pending 状态,当一个健被删除的时候,这只会在 me_value 不为空的时候出现。 +3. Dummy:先前保存了一个 Active 的键值对,但是这个键值对被删除了并且一个活跃的键值对还没有填入该位置,Dummy 可以转变为 Active 当删除的时候,Dummy 的位置不能被重新使用,一旦发生碰撞,探针序列就无法知道这对键值对曾是活跃的键值对。 4. Pending:索引>=0,键!=空,值=空(仅拆分),尚未插入到拆分表中。 - ## 字典的两种类型 -python的字典类型中包含了两种联合字典(split-table dictionaries)与分离字典(combined-table dictonaries)。详细的信息可查看有关dict的描述[pep-0412]()。 +python 的字典类型中包含了两种联合字典(split-table dictionaries)与分离字典(combined-table dictonaries)。详细的信息可查看有关 dict 的描述[pep-0412](https://www.python.org/dev/peps/pep-0412/)。 ### split-table dictionaries -当被创建的字典是用来保存object的\_\_dict\_\_属性时,该字典才会创建为一个split-table,它们的健表都被缓存在类型属性中,并且允许所有该类型的实例都可以共享该keys。当出现一个事件讲字典的属性值进行改变的时候,个别字典讲慢慢的转化成组合表的形式。这就保证了在大部分的应用场景下很高的内存利用效率,并保证了在各个场景下的正确性。当split-dict重新改变大小,它会立马改变为一个combined-table,如果重置大小作为保存实例属性的结果,并且只有一个该object的实例,字典会立马再变为一个split-table。如果从split-table中删除一个key, value,它不会删除keys tables中对应的该值,而只是将values数值中移除了该value。 +当被创建的字典是用来保存 object 的\_\_dict\_\_属性时,该字典才会创建为一个 split-table,它们的健表都被缓存在类型属性中,并且允许所有该类型的实例都可以共享该 keys。当出现一个事件讲字典的属性值进行改变的时候,个别字典讲慢慢的转化成组合表的形式。这就保证了在大部分的应用场景下很高的内存利用效率,并保证了在各个场景下的正确性。当 split-dict 重新改变大小,它会立马改变为一个 combined-table,如果重置大小作为保存实例属性的结果,并且只有一个该 object 的实例,字典会立马再变为一个 split-table。如果从 split-table 中删除一个 key, value,它不会删除 keys tables 中对应的该值,而只是将 values 数值中移除了该 value。 ### combined-table dictionaries -直接通过dict內建函数与{}生成的字典,模块和大部分其他字典都会创建为combined-table字典,一个combined-table不会改变为一个split-table字典,该字典的行为方式与最初的字典的行为方式大致相同。 - +直接通过 dict 內建函数与{}生成的字典,模块和大部分其他字典都会创建为 combined-table 字典,一个 combined-table 不会改变为一个 split-table 字典,该字典的行为方式与最初的字典的行为方式大致相同。 ## 容器的相关数据结构 -字典对象是通过PyDictObject来实现数据的,详情如下; +字典对象是通过 PyDictObject 来实现数据的,详情如下; `源文件:`[Include/dictobject.h](https://github.com/python/cpython/blob/v3.7.0/Include/dictobject.h#L17) @@ -73,7 +72,7 @@ typedef struct { } PyDictObject; ``` -其中,PyDictKeysObject的定义如下; +其中,PyDictKeysObject 的定义如下; `源文件:`[Include/dict-common.h](https://github.com/python/cpython/blob/v3.7.0/Objects/dict-common.h#L20) @@ -128,9 +127,9 @@ struct _dictkeysobject { ``` 相关数据结构的内存布局为; -![python_dict_mem](./python_dict_mem.png) +![python_dict_mem](dict-mem.png) -## Python字典示例 +## Python 字典示例 本次示例脚本如下: @@ -142,7 +141,7 @@ d.pop('1') ``` -通过Python的反汇编工具获取字节码; +通过 Python 的反汇编工具获取字节码; ```shell python -m dis dict_test.py @@ -173,11 +172,11 @@ python -m dis dict_test.py 32 RETURN_VALUE ``` -通过字节码指令可知,首先调用了BUILD_MAP来创建一个新的字典,接着就对新建的字典d进行了赋值操作与更新操作,最后调用了pop方法删除一个key。接下来就详细分析一下相关流程。 +通过字节码指令可知,首先调用了 BUILD_MAP 来创建一个新的字典,接着就对新建的字典 d 进行了赋值操作与更新操作,最后调用了 pop 方法删除一个 key。接下来就详细分析一下相关流程。 ## 字典的初始化流程 -通过查找BUILD_MAP的虚拟机执行函数; +通过查找 BUILD_MAP 的虚拟机执行函数; `源文件:`[Python/ceval.c](https://github.com/python/cpython/blob/v3.7.0/Python/ceval.c#L2357) @@ -212,7 +211,7 @@ switch (opcode) { } ``` -从该函数的执行可知,初始化的函数是从_PyDict_NewPresized开始,该函数就是生成并初始化一个字典; +从该函数的执行可知,初始化的函数是从\_PyDict_NewPresized 开始,该函数就是生成并初始化一个字典; `源文件:`[Objects/dictobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/dictobject.c#L1240) @@ -224,7 +223,7 @@ _PyDict_NewPresized(Py_ssize_t minused) { const Py_ssize_t max_presize = 128 * 1024;  // 字典最大的容量 Py_ssize_t newsize; - PyDictKeysObject *new_keys; + PyDictKeysObject *new_keys; /* There are no strict guarantee that returned dict can contain minused * items without resize. So we create medium size dict instead of very @@ -249,7 +248,7 @@ _PyDict_NewPresized(Py_ssize_t minused) } ``` -首先,先计算出需要生成的字典的大小,然后再初始化一个PyDictKeysObject,最后就生成一个PyDictObject返回。继续查看new_keys_object的执行流程; +首先,先计算出需要生成的字典的大小,然后再初始化一个 PyDictKeysObject,最后就生成一个 PyDictObject 返回。继续查看 new_keys_object 的执行流程; `源文件:`[Objects/dictobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/dictobject.c#L503) @@ -298,12 +297,12 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size) dk->dk_lookup = lookdict_unicode_nodummy; // 设置查找函数 dk->dk_nentries = 0; memset(&dk->dk_indices[0], 0xff, es * size); // 将申请的内存置空 - memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable); + memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable); return dk; } ``` -主要就是通过传入的size,检查是否超过设置的大小,检查是否有缓存的字典数据可用,如果没有则申请内存重新生成一个dk,最后进行申请到的内存讲内容清空。接着就会进行new_dict初始化数据; +主要就是通过传入的 size,检查是否超过设置的大小,检查是否有缓存的字典数据可用,如果没有则申请内存重新生成一个 dk,最后进行申请到的内存讲内容清空。接着就会进行 new_dict 初始化数据; `源文件:`[Objects/dictobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/dictobject.c#L568) @@ -339,11 +338,11 @@ new_dict(PyDictKeysObject *keys, PyObject **values) } ``` -new_dict就是根据keys,values设置到从缓冲池或者新生成一个dict对象,最后返回。至此,dict的创建工作已经完成。 +new_dict 就是根据 keys,values 设置到从缓冲池或者新生成一个 dict 对象,最后返回。至此,dict 的创建工作已经完成。 ## 字典的插入与查找 -通过字节码的指令STORE_SUBSCR可知,该命令就是讲'1'作为key, '2'作为value插入到d中,此时查看该执行函数; +通过字节码的指令 STORE_SUBSCR 可知,该命令就是讲'1'作为 key, '2'作为 value 插入到 d 中,此时查看该执行函数; `源文件:`[Python/ceval.c](https://github.com/python/cpython/blob/v3.7.0/Python/ceval.c#L1561) @@ -354,7 +353,7 @@ switch (opcode) { TARGET(STORE_SUBSCR) { PyObject *sub = TOP(); // 第一个值为key - PyObject *container = SECOND(); // 该为字典对象 + PyObject *container = SECOND(); // 该为字典对象 PyObject *v = THIRD(); // 该为value int err; STACKADJ(-3); @@ -370,7 +369,7 @@ switch (opcode) { } ``` -此时,从栈中取出相关参数,并将这些值传入PyObject_SetItem函数进行处理设置值; +此时,从栈中取出相关参数,并将这些值传入 PyObject_SetItem 函数进行处理设置值; `源文件:`[Objects/abstract.c](https://github.com/python/cpython/blob/v3.7.0/Objects/abstract.c#L186) @@ -385,7 +384,7 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) null_error(); return -1; } - m = o->ob_type->tp_as_mapping;                      // 获取类型的tp_as_mapping方法集      + m = o->ob_type->tp_as_mapping;                      // 获取类型的tp_as_mapping方法集      if (m && m->mp_ass_subscript)                       // 如果有设置该类型 return m->mp_ass_subscript(o, key, value); // 调用该mp_ass_subscript方法 @@ -409,7 +408,7 @@ PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value) } ``` -其中就调用了字典的tp_as_mapping的方法集,并调用了该方法集的mp_ass_subscript方法;此时我们分析一下,dict的tp_as_mapping的方法集。此时就调用了tp_as_mapping的mp_ass_subscript方法,此时就是调用dict的dict_ass_sub方法; +其中就调用了字典的 tp_as_mapping 的方法集,并调用了该方法集的 mp_ass_subscript 方法;此时我们分析一下,dict 的 tp_as_mapping 的方法集。此时就调用了 tp_as_mapping 的 mp_ass_subscript 方法,此时就是调用 dict 的 dict_ass_sub 方法; `源文件:`[Objects/dictobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/dictobject.c#L2040) @@ -425,7 +424,7 @@ dict_ass_sub(PyDictObject *mp, PyObject *v, PyObject *w) } ``` -可知,删除一个key就是PyDict_DelItem,设置一个key就是PyDict_SetItem; +可知,删除一个 key 就是 PyDict_DelItem,设置一个 key 就是 PyDict_SetItem; `源文件:`[Objects/dictobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/dictobject.c#L1433) @@ -457,7 +456,7 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) ``` -insertdict方法就是将生成的方法,插入到字典中去; +insertdict 方法就是将生成的方法,插入到字典中去; `源文件:`[Objects/dictobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/dictobject.c#L987) @@ -471,7 +470,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) Py_INCREF(key); Py_INCREF(value); - if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { + if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { if (insertion_resize(mp) < 0) // 重新设置mp的大小 如果ma_values有值 goto Fail; } @@ -551,7 +550,7 @@ Fail: 首先会调用相关的查找方法,去查找待搜索的值是否已经存在字典中,如果当前字典数据已经满了则会按照增长大小的函数生成一个新的字典,并把旧数据设置到新的字典中,当找到的字典匹配时则返回。 -其中dk_lookup对应的方法,在初始化之后对应的是lookdict_unicode_nodummy; +其中 dk_lookup 对应的方法,在初始化之后对应的是 lookdict_unicode_nodummy; `源文件:`[Objects/dictobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/dictobject.c#L813) @@ -586,7 +585,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, *value_addr = NULL;                       // 讲key对应的value设置为空 return DKIX_EMPTY;                        // 返回 } - PyDictKeyEntry *ep = &ep0[ix];             // 获取该位置元素值 + PyDictKeyEntry *ep = &ep0[ix];             // 获取该位置元素值 assert(ep->me_key != NULL); assert(PyUnicode_CheckExact(ep->me_key)); if (ep->me_key == key || @@ -601,12 +600,11 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, } ``` -该函数的主要工作就是查找,字典中是否有空余的值,或者如果找到了满足hash值与key相同的就将value设置为找到的值(这也是字典查找的核心逻辑)。至此,字典的插入的大致流程已经分析完毕。 - +该函数的主要工作就是查找,字典中是否有空余的值,或者如果找到了满足 hash 值与 key 相同的就将 value 设置为找到的值(这也是字典查找的核心逻辑)。至此,字典的插入的大致流程已经分析完毕。 -## Python字典的操作测试 +## Python 字典的操作测试 -现在我们动手观看一下具体的操作实例,首先声明,该例子仅供调试使用,目前调试的字典的key与value都是float类型并且不能del或者pop其中的key。操作字典如下所示; +现在我们动手观看一下具体的操作实例,首先声明,该例子仅供调试使用,目前调试的字典的 key 与 value 都是 float 类型并且不能 del 或者 pop 其中的 key。操作字典如下所示; ```python d = {20000:2} @@ -614,7 +612,7 @@ d[1] = 2 d[3] = 2 ``` -首先,讲如下代码插入到dictobject.c的1060行; +首先,讲如下代码插入到 dictobject.c 的 1060 行; ```c // 测试代码 @@ -652,43 +650,43 @@ if (ix1 == 0){ 然后编译运行; ```python -Python 3.7.3 (default, May 22 2019, 16:17:57) +Python 3.7.3 (default, May 22 2019, 16:17:57) [GCC 7.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> d = {20000:2} found value : 20000 - indices index values :0 -1 -1 -1 -1 -1 -1 -1 + indices index values :0 -1 -1 -1 -1 -1 -1 -1 size : 8 found value while  key : 20000 value : 2 ``` -其中为什么初始化的时候输入20000,是根据代码找到相关的key值,因为字典也被python自身实现的结构中引用了多次,所以我们就设置了一个特殊值来跟踪我们想要的字典;当d初始化的时候,就输出如上所示内容;我们接下来继续操作; +其中为什么初始化的时候输入 20000,是根据代码找到相关的 key 值,因为字典也被 python 自身实现的结构中引用了多次,所以我们就设置了一个特殊值来跟踪我们想要的字典;当 d 初始化的时候,就输出如上所示内容;我们接下来继续操作; ```python >>> d = {20000:2} found value : 20000 - indices index values :0 -1 -1 -1 -1 -1 -1 -1 + indices index values :0 -1 -1 -1 -1 -1 -1 -1 size : 8 found value while  key : 20000 value : 2 >>> d[2] = 3 found value : 20000 - indices index values :0 -1 1 -1 -1 -1 -1 -1 + indices index values :0 -1 1 -1 -1 -1 -1 -1 size : 8 found value while  key : 20000 value : 2 size : 8 found value while  key : 2 value : 3 >>> d[3] = 4 found value : 20000 - indices index values :0 -1 1 2 -1 -1 -1 -1 + indices index values :0 -1 1 2 -1 -1 -1 -1 size : 8 found value while  key : 20000 value : 2 size : 8 found value while  key : 2 value : 3 size : 8 found value while  key : 3 value : 4 >>> d[5] = 6 found value : 20000 - indices index values :0 -1 1 2 -1 3 -1 -1 + indices index values :0 -1 1 2 -1 3 -1 -1 size : 8 found value while  key : 20000 value : 2 size : 8 found value while  key : 2 value : 3 size : 8 found value while  key : 3 value : 4 size : 8 found value while  key : 5 value : 6 >>> d[7] = 8 found value : 20000 - indices index values :0 -1 1 2 -1 3 -1 4 + indices index values :0 -1 1 2 -1 3 -1 4 size : 8 found value while  key : 20000 value : 2 size : 8 found value while  key : 2 value : 3 size : 8 found value while  key : 3 value : 4 @@ -696,13 +694,13 @@ size : 8 found value while  key : 5 value : 6 size : 8 found value while  key : 7 value : 8 ``` -此后我们一直添加值进d,从输出信息可知,index就是记录了PyDictKeyEntry的索引值,-1就表示该处未使用。 -当我们继续向d中添加内容时; +此后我们一直添加值进 d,从输出信息可知,index 就是记录了 PyDictKeyEntry 的索引值,-1 就表示该处未使用。 +当我们继续向 d 中添加内容时; ```python >>> d[9] = 10 found value : 20000 - indices index values :0 -1 1 2 -1 3 -1 4 -1 5 -1 -1 -1 -1 -1 -1 + indices index values :0 -1 1 2 -1 3 -1 4 -1 5 -1 -1 -1 -1 -1 -1 size : 16 found value while  key : 20000 value : 2 size : 16 found value while  key : 2 value : 3 size : 16 found value while  key : 3 value : 4 @@ -711,7 +709,7 @@ size : 16 found value while  key : 7 value : 8 size : 16 found value while  key : 9 value : 10 >>> d[10] = 11 found value : 20000 - indices index values :0 -1 1 2 -1 3 -1 4 -1 5 6 -1 -1 -1 -1 -1 + indices index values :0 -1 1 2 -1 3 -1 4 -1 5 6 -1 -1 -1 -1 -1 size : 16 found value while  key : 20000 value : 2 size : 16 found value while  key : 2 value : 3 size : 16 found value while  key : 3 value : 4 @@ -721,4 +719,4 @@ size : 16 found value while  key : 9 value : 10 size : 16 found value while  key : 10 value : 11 ``` -从输出内容可知,字典的大小随之改变了,这也说明了python字典的最佳大小容量限定在1/2到2/3之间,如果超过这个阈值则字典就会自动扩容,扩容的策略大家可详细查看源码。 +从输出内容可知,字典的大小随之改变了,这也说明了 python 字典的最佳大小容量限定在 1/2 到 2/3 之间,如果超过这个阈值则字典就会自动扩容,扩容的策略大家可详细查看源码。 diff --git a/objects/PyListStructure.png b/objects/list-object/PyListStructure.png similarity index 100% rename from objects/PyListStructure.png rename to objects/list-object/PyListStructure.png diff --git a/objects/list-object.md b/objects/list-object/index.md similarity index 100% rename from objects/list-object.md rename to objects/list-object/index.md diff --git a/objects/long-object.md b/objects/long-object/index.md similarity index 93% rename from objects/long-object.md rename to objects/long-object/index.md index 6722b52..bbcd77b 100644 --- a/objects/long-object.md +++ b/objects/long-object/index.md @@ -18,7 +18,6 @@ CPython3 只保留了 `PyLongObject` typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ ``` - `源文件:`[Include/longintrepr.h](https://github.com/python/cpython/blob/v3.7.0/Include/longintrepr.h#L85) ```c @@ -57,7 +56,6 @@ struct _longobject { 从源码可以看出 PyLongObject 是变长对象 - ## 类型对象 PyLong_Type `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L5379) @@ -205,11 +203,11 @@ long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase) 从 long_new_impl 函数可以看出有如下几种情况 -- x == NULL 且 obase != NULL 调用 PyLong_FromLong -- obase 为NULL 调用 PyNumber_Long +- x == NULL 且 obase != NULL 调用 PyLong_FromLong +- obase 为 NULL 调用 PyNumber_Long - x 和 obase 都不为 NULL - - PyUnicode 调用PyLong_FromUnicodeObject,最终调用PyLong_FromString - - PyByteArray/PyBytes 调用_PyLong_FromBytes,最终调用PyLong_FromString + - PyUnicode 调用 PyLong_FromUnicodeObject,最终调用 PyLong_FromString + - PyByteArray/PyBytes 调用\_PyLong_FromBytes,最终调用 PyLong_FromString ## 小整数对象 @@ -343,6 +341,7 @@ _PyLong_Init(void) `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L1581) 在 **long_to_decimal_string_internal**中添加如下代码并重新编译安装 + ```c // Objects/longobject.c static int @@ -372,7 +371,7 @@ long_to_decimal_string_internal(PyObject *aa, } ``` -编译安装后进入python解释器输入如下代码 +编译安装后进入 python 解释器输入如下代码 ```python num = 9223372043297226753 @@ -388,9 +387,9 @@ print(num) 如下图所示 -![longobject storage](longobject_storage.png) +![longobject storage](longo-storage.png) -注:这里的 30 是由 **PyLong_SHIFT** 决定的,64位系统中,**PyLong_SHIFT** 为30,否则 **PyLong_SHIFT** 为15 +注:这里的 30 是由 **PyLong_SHIFT** 决定的,64 位系统中,**PyLong_SHIFT** 为 30,否则 **PyLong_SHIFT** 为 15 ## 整数对象的数值操作 @@ -481,7 +480,7 @@ long_add(PyLongObject *a, PyLongObject *b) } ``` -可以看到整数的加法运算函数long_add根据 a、b的ob_size 又细分为两个函数 (x_add 和 x_sub) 做处理 +可以看到整数的加法运算函数 long_add 根据 a、b 的 ob_size 又细分为两个函数 (x_add 和 x_sub) 做处理 `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L2991) @@ -523,10 +522,9 @@ x_add(PyLongObject *a, PyLongObject *b) } ``` -加法运算函数 x_add 从 ob_digit 数组的低位开始依次按位相加,carry做进位处理,然后处理a对象的高位数字,最后使用 long_normalize 函数调整 ob_size,确保ob_digit[abs(ob_size)-1]不为零,这与普通四则运算的加法运算相同,只不过进位单元不同而已 - -![longobject x_add](longobject_x_add.png) +加法运算函数 x_add 从 ob_digit 数组的低位开始依次按位相加,carry 做进位处理,然后处理 a 对象的高位数字,最后使用 long_normalize 函数调整 ob_size,确保 ob_digit[abs(ob_size)-1]不为零,这与普通四则运算的加法运算相同,只不过进位单元不同而已 +![longobject x_add](long-x-add.png) `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L3025) @@ -593,9 +591,9 @@ x_sub(PyLongObject *a, PyLongObject *b) ``` 与普通四则运算减法相同,数不够大则向高一位借位, -减法运算函数 x_sub 的示例图如下,注:PyLong_SHIFT为30 +减法运算函数 x_sub 的示例图如下,注:PyLong_SHIFT 为 30 -![longobject x_sub](longobject_x_sub.png) +![longobject x_sub](long-x-sub.png) ### 整数相乘 @@ -627,11 +625,10 @@ long_mul(PyLongObject *a, PyLongObject *b) } ``` -k_mul函数是一种快速乘法 [源文件]( -https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L3268) +k_mul 函数是一种快速乘法 [源文件](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L3268) -> Karatsuba的算法主要是用于两个大数的乘法,极大提高了运算效率,相较于普通乘法降低了复杂度,并在其中运用了递归的思想。 -> 基本的原理和做法是将位数很多的两个大数x和y分成位数较少的数,每个数都是原来x和y位数的一半。 +> Karatsuba 的算法主要是用于两个大数的乘法,极大提高了运算效率,相较于普通乘法降低了复杂度,并在其中运用了递归的思想。 +> 基本的原理和做法是将位数很多的两个大数 x 和 y 分成位数较少的数,每个数都是原来 x 和 y 位数的一半。 > 这样处理之后,简化为做三次乘法,并附带少量的加法操作和移位操作。 -具体可以看wiki [Karatsuba算法](https://www.wikiwand.com/zh-hans/Karatsuba算法)的实现 +具体可以看 wiki [Karatsuba 算法](https://www.wikiwand.com/zh-hans/Karatsuba算法)的实现 diff --git a/objects/longobject_storage.png b/objects/long-object/long-storage.png similarity index 100% rename from objects/longobject_storage.png rename to objects/long-object/long-storage.png diff --git a/objects/longobject_x_add.png b/objects/long-object/long-x-add.png similarity index 100% rename from objects/longobject_x_add.png rename to objects/long-object/long-x-add.png diff --git a/objects/longobject_x_sub.png b/objects/long-object/long-x-sub.png similarity index 100% rename from objects/longobject_x_sub.png rename to objects/long-object/long-x-sub.png diff --git a/objects/PyObject.jpg b/objects/object/PyObject.jpg similarity index 100% rename from objects/PyObject.jpg rename to objects/object/PyObject.jpg diff --git a/objects/PyVarObject.jpg b/objects/object/PyVarObject.jpg similarity index 100% rename from objects/PyVarObject.jpg rename to objects/object/PyVarObject.jpg diff --git a/objects/object.md b/objects/object/index.md similarity index 84% rename from objects/object.md rename to objects/object/index.md index 4eb8c5c..b10bc34 100644 --- a/objects/object.md +++ b/objects/object/index.md @@ -1,10 +1,10 @@ # Python 对象初探 -在Python的世界一切皆对象,不论是整数,还是字符串,甚至连类型、函数等都是一种对象。 +在 Python 的世界一切皆对象,不论是整数,还是字符串,甚至连类型、函数等都是一种对象。 ## 对象的分类 -以下是Python对象的大致的一个分类 +以下是 Python 对象的大致的一个分类 - Fundamental 对象: 类型对象 - Numeric 对象: 数值对象 @@ -12,13 +12,13 @@ - Mapping 对象: 类似 C++中的 map 的关联对象 - Internal 对象: Python 虚拟机在运行时内部使用的对象 -![object category](object_category.jpg) +![object category](object-category.jpg) ## 对象机制的基石 PyObject 对于初学者来说这么多类型的对象怎么学?别着急,我们后续章节会解答。 -在开始我们的学习之旅之前,我们要先认识一个结构体**PyObject**,可以说Python的对象机制就是基于**PyObject**拓展开来的,所以我们先看看**PyObject** 到底长什么样。 +在开始我们的学习之旅之前,我们要先认识一个结构体**PyObject**,可以说 Python 的对象机制就是基于**PyObject**拓展开来的,所以我们先看看**PyObject** 到底长什么样。 `源文件:`[Include/object.h](https://github.com/python/cpython/blob/v3.7.0/Include/object.h#L106) @@ -35,7 +35,7 @@ typedef struct _object { } PyObject; ``` -Python中的所有对象都拥有一些相同的内容,而这些内容就定义在**PyObject**中, +Python 中的所有对象都拥有一些相同的内容,而这些内容就定义在**PyObject**中, **PyObject** 包含 一个用于垃圾回收的双向链表,一个引用计数变量 `ob_refcnt` 和 一个类型对象指针`ob_type` @@ -43,7 +43,7 @@ Python中的所有对象都拥有一些相同的内容,而这些内容就定 ## 定长对象与变长对象 -Python对象除了前面提到的那种分类方法外,还可以分为定长对象和变长对象这两种形式。 +Python 对象除了前面提到的那种分类方法外,还可以分为定长对象和变长对象这两种形式。 变长对象都拥有一个相同的内容 **PyVarObject**,而 **PyVarObject**也是基于**PyObject**扩展的。 @@ -65,7 +65,6 @@ typedef struct { } PyVarObject; ``` - ![PyVarObject](PyVarObject.jpg) ## 类型对象 @@ -78,6 +77,7 @@ typedef struct { 接下来我们看一下`struct _typeobject`代码 在 **PyTypeObject** 的定义中包含许多信息,主要分类以下几类: + - 类型名, tp_name, 主要用于 Python 内部调试用 - 创建该类型对象时分配的空间大小信息,即 `tp_basicsize` 和 `tp_itemsize` - 与该类型对象相关的操作信息(如 `tp_print` 这样的函数指针) @@ -122,7 +122,6 @@ typedef struct _typeobject { } PyTypeObject; ``` - ## 类型的类型 在 **PyTypeObjet** 定义开始有一个宏`PyOject_VAR_HEAD`,查看源码可知 **PyTypeObjet** 是一个变长对象 @@ -155,10 +154,9 @@ PyTypeObject PyType_Type = { `PyType_Type` 在类型机制中至关重要,所有用户自定义 `class` 所 对应的 `PyTypeObject` 对象都是通过 `PyType_Type`创建的 - 接下来我们看 `PyLong_Type` 是怎么与 `PyType_Type` 建立联系的。 -前面提到,在Python中,每一个对象都将自己的引用计数、类型信息保存在开始的部分中。 -为了方便对这部分内存初始化,Python中提供了几个有用的宏: +前面提到,在 Python 中,每一个对象都将自己的引用计数、类型信息保存在开始的部分中。 +为了方便对这部分内存初始化,Python 中提供了几个有用的宏: `源文件:`[Include/object.h](https://github.com/python/cpython/blob/v3.7.0/Include/object.h#L69) @@ -195,26 +193,26 @@ PyTypeObject PyLong_Type = { 下图是对象运行时的图像表现 -![](object_runtime_relation.jpg) - +![](object-runtime-relation.jpg) ## 对象的创建 -Python创建对象有两种方式 +Python 创建对象有两种方式 -### 范型API 或称为 AOL (Abstract Object Layer) +### 范型 API 或称为 AOL (Abstract Object Layer) -这类API通常形如`PyObject_XXX`这样的形式。可以应用在任何Python对象上, +这类 API 通常形如`PyObject_XXX`这样的形式。可以应用在任何 Python 对象上, 如`PyObject_New`。创建一个整数对象的方式 ```c PyObject* longobj = PyObject_New(Pyobject, &PyLong_Type); ``` -### 与类型相关的API 或称为 COL (Concrete Object Layer) +### 与类型相关的 API 或称为 COL (Concrete Object Layer) + +这类 API 通常只能作用于某一种类型的对象上,对于每一种内建对象 +Python 都提供了这样一组 API。例如整数对象,我们可以利用如下的 API 创建 -这类API 通常只能作用于某一种类型的对象上,对于每一种内建对象 -Python都提供了这样一组API。例如整数对象,我们可以利用如下的API创建 ```c PyObject *longObj = PyLong_FromLong(10); ``` @@ -225,11 +223,11 @@ PyObject *longObj = PyLong_FromLong(10); 所定义的操作,这些操作直接决定着一个对象在运行时所表现出的行为,比如 **PyTypeObject** 中的 `tp_hash` 指明了该类型对象如何生成其`hash`值。 在**PyTypeObject**的代码中,我们还可以看到非常重要的三组操作族 + - `PyNumberMethods *tp_as_number` - `PySequenceMethods *tp_as_sequence` - `PyMappingMethods *tp_as_mapping` - **PyNumberMethods** 的代码如下 `源文件:`[Include/object.h](https://github.com/python/cpython/blob/v3.7.0/Include/object.h#L240) @@ -284,15 +282,14 @@ PyTypeObject PyLong_Type = { `PySequenceMethods *tp_as_sequence` 和 `PyMappingMethods *tp_as_mapping`的分析与`PyNumberMethods *tp_as_number` 相同,大家可以自行查阅源码 - ## 对象的多态性 -Python创建一个对象比如 **PyLongObject** 时,会分配内存进行初始化,然后 -Python内部会用 `PyObject*` 变量来维护这个对象,其他对象也与此类似 +Python 创建一个对象比如 **PyLongObject** 时,会分配内存进行初始化,然后 +Python 内部会用 `PyObject*` 变量来维护这个对象,其他对象也与此类似 所以在 Python 内部各个函数之间传递的都是一种范型指针 `PyObject*` 我们不知道这个指针所指的对象是什么类型,只能通过所指对象的 `ob_type` 域 -动态进行判断,而Python正是通过 `ob_type` 实现了多态机制 +动态进行判断,而 Python 正是通过 `ob_type` 实现了多态机制 考虑以下的 calc_hash 函数 @@ -305,7 +302,7 @@ calc_hash(PyObject* object) } ``` -如果传递给 calc_hash 函数的指针是一个 `PyLongObject*`,那么它会调用 PyLongObject 对象对应的类型对象中定义的 hash操作`tp_hash`,`tp_hash`可以在**PyTypeObject**中找到, +如果传递给 calc_hash 函数的指针是一个 `PyLongObject*`,那么它会调用 PyLongObject 对象对应的类型对象中定义的 hash 操作`tp_hash`,`tp_hash`可以在**PyTypeObject**中找到, 而具体赋值绑定我们可以在 `PyLong_Type` 初始化代码中看到绑定的是`long_hash`函数 `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L5379) @@ -323,7 +320,7 @@ PyTypeObject PyLong_Type = { }; ``` -如果指针是一个 `PyUnicodeObject*`,那么就会调用 PyUnicodeObject 对象对应的类型对象中定义的hash操作,查看源码可以看到 实际绑定的是 `unicode_hash`函数 +如果指针是一个 `PyUnicodeObject*`,那么就会调用 PyUnicodeObject 对象对应的类型对象中定义的 hash 操作,查看源码可以看到 实际绑定的是 `unicode_hash`函数 `源文件:`[Objects/unicodeobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/unicodeobject.c#L15066) @@ -347,11 +344,11 @@ Python 通过引用计数来管理维护对象在内存中的存在与否 Python 中的每个东西都是一个对象, 都有`ob_refcnt` 变量,这个变量维护对象的引用计数,从而最终决定该对象的创建与销毁 -在Python中,主要通过 `Py_INCREF(op)`与`Py_DECREF(op)` 这两个宏 -来增加和减少对一个对象的引用计数。当一个对象的引用计数减少到0之后, +在 Python 中,主要通过 `Py_INCREF(op)`与`Py_DECREF(op)` 这两个宏 +来增加和减少对一个对象的引用计数。当一个对象的引用计数减少到 0 之后, `Py_DECREF`将调用该对象的`tp_dealloc`来释放对象所占用的内存和系统资源; -但这并不意味着最终一定会调用 `free` 释放内存空间。因为频繁的申请、释放内存会大大降低Python的执行效率。因此Python中大量采用了内存对象池的技术,使得对象释放的空间归还给内存池而不是直接`free`,后续使用可先从对象池中获取 +但这并不意味着最终一定会调用 `free` 释放内存空间。因为频繁的申请、释放内存会大大降低 Python 的执行效率。因此 Python 中大量采用了内存对象池的技术,使得对象释放的空间归还给内存池而不是直接`free`,后续使用可先从对象池中获取 `源文件:`[Include/object.h](https://github.com/python/cpython/blob/v3.7.0/Include/object.h#L777) diff --git a/objects/object_category.jpg b/objects/object/object-category.jpg similarity index 100% rename from objects/object_category.jpg rename to objects/object/object-category.jpg diff --git a/objects/object_runtime_relation.jpg b/objects/object/object-runtime-relation.jpg similarity index 100% rename from objects/object_runtime_relation.jpg rename to objects/object/object-runtime-relation.jpg diff --git a/objects/set-object.md b/objects/set-object/index.md similarity index 87% rename from objects/set-object.md rename to objects/set-object/index.md index d34f01b..74bbcd7 100644 --- a/objects/set-object.md +++ b/objects/set-object/index.md @@ -1,10 +1,10 @@ -# python集合 +# python 集合 -set是无序且不重复的集合,是可变的,通常用来从列表中删除重复项以及计算数学运算,如交集、并集、差分和对称差分等集合操作。set 支持 x in set, len(set),和 for x in set。作为一个无序的集合,set不记录元素位置或者插入点。因此,sets不支持 indexing, 或其它类序列的操作。 +set 是无序且不重复的集合,是可变的,通常用来从列表中删除重复项以及计算数学运算,如交集、并集、差分和对称差分等集合操作。set 支持 x in set, len(set),和 for x in set。作为一个无序的集合,set 不记录元素位置或者插入点。因此,sets 不支持 indexing, 或其它类序列的操作。 -## python集合概述 +## python 集合概述 -在set中,对应的set的值的存储是通过结构setentry来保存数据值的; +在 set 中,对应的 set 的值的存储是通过结构 setentry 来保存数据值的; `源文件:`[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L26) @@ -15,7 +15,7 @@ typedef struct { } setentry; ``` -key就是保存的数据,hash就是保存的数据的hash,便于查找,set也是基于hash表来实现。对应的setentry所对应的set的数据结构如下; +key 就是保存的数据,hash 就是保存的数据的 hash,便于查找,set 也是基于 hash 表来实现。对应的 setentry 所对应的 set 的数据结构如下; `源文件:`[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42) @@ -46,11 +46,11 @@ typedef struct { } PySetObject; ``` -一个set就对应一个PySetObject类型数据,set会根据保存的元素自动调整大小。相关的内存布局如下; +一个 set 就对应一个 PySetObject 类型数据,set 会根据保存的元素自动调整大小。相关的内存布局如下; -![内存图片](./python_set.png) +![内存图片](set.png) -## python集合(set)示例 +## python 集合(set)示例 示例脚本如下: @@ -63,7 +63,7 @@ set_a.update({3,}) set_a.union({1,5}) ``` -通过python反汇编获取该脚本的字节码; +通过 python 反汇编获取该脚本的字节码; ``` python -m dis set_test.py @@ -113,12 +113,11 @@ python -m dis set_test.py 89 RETURN_VALUE ``` +通过该字节码指令可知,创建 set 调用了 BUILD_SET 指令,初始化完成之后,就调用 set 的 add 方法添加元素,调用 remove 删除元素,调用 update 来更新集合,通过 union 来合并集合。接下来就详细分析一下相关的操作流程。 -通过该字节码指令可知,创建set调用了BUILD_SET指令,初始化完成之后,就调用set的add方法添加元素,调用remove删除元素,调用update来更新集合,通过union来合并集合。接下来就详细分析一下相关的操作流程。 +## set 的创建与初始化 -## set的创建与初始化 - -查找BUILD_SET的虚拟机执行函数如下; +查找 BUILD_SET 的虚拟机执行函数如下; `源文件:`[Python/ceval.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Python/ceval.c#L2318) @@ -148,11 +147,10 @@ python -m dis set_test.py ``` -此时继续查看PySet_New函数的执行流程; +此时继续查看 PySet_New 函数的执行流程; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286) - ```c PyObject * PySet_New(PyObject *iterable) @@ -191,11 +189,11 @@ make_new_set(PyTypeObject *type, PyObject *iterable) } ``` -从PySet_New的执行流程可知,字典的初始化过程就是初始化相关数据结构。 +从 PySet_New 的执行流程可知,字典的初始化过程就是初始化相关数据结构。 -## set的插入 +## set 的插入 -在本例的初始化过程中,由于传入了初始值1,2,所以会在执行字节码指令的时候,执行PySet_Add,该函数的本质与set_a.add(3)本质都调用了更底层set_add_key函数; +在本例的初始化过程中,由于传入了初始值 1,2,所以会在执行字节码指令的时候,执行 PySet_Add,该函数的本质与 set_a.add(3)本质都调用了更底层 set_add_key 函数; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338) @@ -213,7 +211,7 @@ PySet_Add(PyObject *anyset, PyObject *key) } ``` -继续查看set_add_key函数的执行过程; +继续查看 set_add_key 函数的执行过程; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419) @@ -225,7 +223,7 @@ set_add_key(PySetObject *so, PyObject *key) if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { - hash = PyObject_Hash(key); // 获取传入值的hash值 + hash = PyObject_Hash(key); // 获取传入值的hash值 if (hash == -1) // 如果不能hash则返回-1 return -1; } @@ -233,7 +231,7 @@ set_add_key(PySetObject *so, PyObject *key) } ``` -该函数主要就是检查传入的key是否能够被hash,如果能够被hash则直接返回,如果能被hash则继续调用set_add_entry函数将值加入到set中; +该函数主要就是检查传入的 key 是否能够被 hash,如果能够被 hash 则直接返回,如果能被 hash 则继续调用 set_add_entry 函数将值加入到 set 中; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L136) @@ -362,33 +360,33 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash) } ``` -此时基本的流程就是通过传入的hash值,如果计算出的索引值,没有值,则直接将该值存入对应的entry中,如果相同则不插入,如果索引对应的值且值不同,则遍历从该索引往后9个位置的值,依次找到有空余位置的值,并将该值设置进去。如果设置该值之后使用的数量占总的申请数量超过了3/5则重新扩充set,扩充的原则就是如果当前的set->used>50000就进行两倍扩充否则就进行四倍扩充。 +此时基本的流程就是通过传入的 hash 值,如果计算出的索引值,没有值,则直接将该值存入对应的 entry 中,如果相同则不插入,如果索引对应的值且值不同,则遍历从该索引往后9个位置的值,依次找到有空余位置的值,并将该值设置进去。如果设置该值之后使用的数量占总的申请数量超过了 3/5 则重新扩充 set,扩充的原则就是如果当前的 set->used>50000 就进行两倍扩充否则就进行四倍扩充。 -插入的概述如下,默认s初始化为空; +插入的概述如下,默认 s 初始化为空; ```python s.add(1) // index = 1 & 7 = 1 ``` -![插入1](./set_insert_one.png) +![插入1](set-insert-one.png) ```python s.add(2) // index = 2 & 7 = 2 ``` -![插入2](./set_insert_two.png) +![插入2](set-insert-two.png) ```python s.add(7) // index = 9 & 7 = 1 ``` -![插入9](./set_insert_nine.png) +![插入9](set-insert-nine.png) -大致的set的插入过程执行完毕。 +大致的 set 的插入过程执行完毕。 -## set的删除 +## set 的删除 -set的删除操作主要集中在set_remove()函数上,如下示例; +set 的删除操作主要集中在 set_remove()函数上,如下示例; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L1921) @@ -422,7 +420,7 @@ set_remove(PySetObject *so, PyObject *key) } ``` -此时就会调用set_discard_key方法来讲对应的entry设置为dummy;set_discard_key方法如下; +此时就会调用 set_discard_key 方法来讲对应的 entry 设置为 dummy;set_discard_key 方法如下; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447) @@ -443,7 +441,7 @@ set_discard_key(PySetObject *so, PyObject *key) } ``` -该函数主要就是做了检查key是否可用hash的检查,此时如果可用hash则调用set_discard_entry方法; +该函数主要就是做了检查 key 是否可用 hash 的检查,此时如果可用 hash 则调用 set_discard_entry 方法; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L400) @@ -469,11 +467,11 @@ set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash) } ``` -此时就是查找该值,如果找到该值并将该值设置为dummy,并且将used值减1,此处没有减去fill的数量,从此处可知,fill包括所有曾经申请过的数量。 +此时就是查找该值,如果找到该值并将该值设置为 dummy,并且将 used 值减1,此处没有减去 fill 的数量,从此处可知,fill 包括所有曾经申请过的数量。 -## set的resize +## set 的 resize -set的resize主要依靠set_table_reseize函数来实现; +set 的 resize 主要依靠 set_table_reseize 函数来实现; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L302) @@ -559,7 +557,7 @@ set_table_resize(PySetObject *so, Py_ssize_t minused) ``` -主要是检查是否table相同并且需要重新resize的值,然后判断是否fill与used相同,如果相同则全部插入,如果不同,则遍历旧table讲不为空并且不为dummy的值插入到新表中; +主要是检查是否 table 相同并且需要重新 resize 的值,然后判断是否 fill 与 used 相同,如果相同则全部插入,如果不同,则遍历旧 table 讲不为空并且不为 dummy 的值插入到新表中; `源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L267) @@ -592,5 +590,4 @@ set_insert_clean(setentry *table, size_t mask, PyObject *key, Py_hash_t hash) } ``` -set的resize的操作基本如上所述。 - +set 的 resize 的操作基本如上所述。 diff --git a/objects/set_insert_nine.png b/objects/set-object/set-insert-nine.png similarity index 100% rename from objects/set_insert_nine.png rename to objects/set-object/set-insert-nine.png diff --git a/objects/set_insert_one.png b/objects/set-object/set-insert-one.png similarity index 100% rename from objects/set_insert_one.png rename to objects/set-object/set-insert-one.png diff --git a/objects/set_insert_two.png b/objects/set-object/set-insert-two.png similarity index 100% rename from objects/set_insert_two.png rename to objects/set-object/set-insert-two.png diff --git a/objects/python_set.png b/objects/set-object/set.png similarity index 100% rename from objects/python_set.png rename to objects/set-object/set.png diff --git a/objects/string-object.md b/objects/simple-interpreter/index.md similarity index 100% rename from objects/string-object.md rename to objects/simple-interpreter/index.md diff --git a/objects/simple-implementation.md b/objects/str-object/index.md similarity index 100% rename from objects/simple-implementation.md rename to objects/str-object/index.md diff --git a/preface/code-organization.md b/preface/code-organization/index.md similarity index 100% rename from preface/code-organization.md rename to preface/code-organization/index.md diff --git a/preface/modify-code.md b/preface/modify-code/index.md similarity index 100% rename from preface/modify-code.md rename to preface/modify-code/index.md diff --git a/preface/unix-linux-build.md b/preface/unix-linux-build/index.md similarity index 100% rename from preface/unix-linux-build.md rename to preface/unix-linux-build/index.md diff --git a/preface/build-files.png b/preface/windows-build/build-files.png similarity index 100% rename from preface/build-files.png rename to preface/windows-build/build-files.png diff --git a/preface/windows-build.md b/preface/windows-build/index.md similarity index 100% rename from preface/windows-build.md rename to preface/windows-build/index.md diff --git a/preface/vs2017-build.png b/preface/windows-build/vs2017-build.png similarity index 100% rename from preface/vs2017-build.png rename to preface/windows-build/vs2017-build.png diff --git a/preface/vs2017-configure.png b/preface/windows-build/vs2017-configure.png similarity index 100% rename from preface/vs2017-configure.png rename to preface/windows-build/vs2017-configure.png diff --git a/preface/vs2017-installation.png b/preface/windows-build/vs2017-installation.png similarity index 100% rename from preface/vs2017-installation.png rename to preface/windows-build/vs2017-installation.png diff --git a/preface/vs2017-properties.png b/preface/windows-build/vs2017-properties.png similarity index 100% rename from preface/vs2017-properties.png rename to preface/windows-build/vs2017-properties.png From f9d1a385d8d6842fcef867f4fac7f6ba71167d00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9D=9E=E6=B3=95=E6=93=8D=E4=BD=9C?= Date: Mon, 5 Aug 2019 10:33:22 +0800 Subject: [PATCH 15/17] Update index.md fix spelling error --- objects/dict-object/index.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/objects/dict-object/index.md b/objects/dict-object/index.md index fd6fac1..cdc42ce 100644 --- a/objects/dict-object/index.md +++ b/objects/dict-object/index.md @@ -21,18 +21,18 @@ typedef struct { 其中,me_hash 就是哈希生成的值,me_key 就是对应的 key 值,me_value 就是对应的值。 在 python 中,在一个 PyDictObject 对象的变化过程中,entry 的状态会在不同的状态间转换。基本上在如下四种状态中转换:Unused、Active、Dummy 和 Pending。 -1. Unused:没有插入任何一个获取的 key 与 value,并且在次之前也没有存储任何的 key,value,每一个 entry 在初始化的时候都会处于这种状态,并且 Unused 会被里面切换到 Active 态,当有 key 插入,这是就是 entry 初始化的状态。 -2. Active:当 index>=0 时,me_key 不为空并且 me_value 不为空,保存了一个键值对,Active 可以转变为 Dummy 或者 Pending 状态,当一个健被删除的时候,这只会在 me_value 不为空的时候出现。 +1. Unused:没有插入任何一个获取的 key 与 value,并且在此之前也没有存储任何的 key,value,每一个 entry 在初始化的时候都会处于这种状态,并且 Unused 会被里面切换到 Active 态,当有 key 插入,这就是 entry 初始化的状态。 +2. Active:当 index>=0 时,me_key 不为空并且 me_value 不为空,保存了一个键值对,Active 可以转变为 Dummy 或者 Pending 状态,当一个键被删除的时候,这只会在 me_value 不为空的时候出现。 3. Dummy:先前保存了一个 Active 的键值对,但是这个键值对被删除了并且一个活跃的键值对还没有填入该位置,Dummy 可以转变为 Active 当删除的时候,Dummy 的位置不能被重新使用,一旦发生碰撞,探针序列就无法知道这对键值对曾是活跃的键值对。 -4. Pending:索引>=0,键!=空,值=空(仅拆分),尚未插入到拆分表中。 +4. Pending:索引>=0,键!=空,值=空(仅拆分),尚未插入到拆分表中。 ## 字典的两种类型 -python 的字典类型中包含了两种联合字典(split-table dictionaries)与分离字典(combined-table dictonaries)。详细的信息可查看有关 dict 的描述[pep-0412](https://www.python.org/dev/peps/pep-0412/)。 +python 的字典类型中包含了两种,分离字典(split-table dictionaries)与联合字典(combined-table dictonaries)。详细的信息可查看有关 dict 的描述[pep-0412](https://www.python.org/dev/peps/pep-0412/)。 ### split-table dictionaries -当被创建的字典是用来保存 object 的\_\_dict\_\_属性时,该字典才会创建为一个 split-table,它们的健表都被缓存在类型属性中,并且允许所有该类型的实例都可以共享该 keys。当出现一个事件讲字典的属性值进行改变的时候,个别字典讲慢慢的转化成组合表的形式。这就保证了在大部分的应用场景下很高的内存利用效率,并保证了在各个场景下的正确性。当 split-dict 重新改变大小,它会立马改变为一个 combined-table,如果重置大小作为保存实例属性的结果,并且只有一个该 object 的实例,字典会立马再变为一个 split-table。如果从 split-table 中删除一个 key, value,它不会删除 keys tables 中对应的该值,而只是将 values 数值中移除了该 value。 +当被创建的字典是用来保存 object 的\_\_dict\_\_属性时,该字典才会创建为一个 split-table,它们的键表都被缓存在类型属性中,并且允许所有该类型的实例都可以共享该 keys。当出现一个事件将字典的属性值进行改变的时候,个别字典将慢慢的转化成组合表的形式。这就保证了在大部分的应用场景下很高的内存利用效率,并保证了在各个场景下的正确性。当 split-dict 重新改变大小,它会立马改变为一个 combined-table,如果重置大小作为保存实例属性的结果,并且只有一个该 object 的实例,字典会立马再变为一个 split-table。如果从 split-table 中删除一个 key, value,它不会删除 keys tables 中对应的该值,而只是将 values 数值中移除了该 value。 ### combined-table dictionaries @@ -55,7 +55,7 @@ typedef struct { PyObject_HEAD /* Number of items in the dictionary */ - Py_ssize_t ma_used;  // 使用的keys个数 + Py_ssize_t ma_used;  // 使用的keys个数 /* Dictionary version: globally unique, value change each time the dictionary is modified */ From 404d29b4562e414abbd18278ceb1d3b89449c464 Mon Sep 17 00:00:00 2001 From: hackerxu Date: Fri, 20 Mar 2020 02:00:50 +0800 Subject: [PATCH 16/17] correct the pic url --- objects/long-object/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/objects/long-object/index.md b/objects/long-object/index.md index bbcd77b..3d86586 100644 --- a/objects/long-object/index.md +++ b/objects/long-object/index.md @@ -387,7 +387,7 @@ print(num) 如下图所示 -![longobject storage](longo-storage.png) +![longobject storage](long-storage.png) 注:这里的 30 是由 **PyLong_SHIFT** 决定的,64 位系统中,**PyLong_SHIFT** 为 30,否则 **PyLong_SHIFT** 为 15 From 9406e3fec1456514f668fbcfa161ac11b6728c63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Mar 2020 11:33:35 +0000 Subject: [PATCH 17/17] Bump lodash.merge from 4.6.1 to 4.6.2 Bumps [lodash.merge](https://github.com/lodash/lodash) from 4.6.1 to 4.6.2. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/commits) Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4cc2f17..9bee6b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5548,9 +5548,9 @@ "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" }, "lodash.merge": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "lodash.pick": { "version": "4.4.0",