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 e8e0b56..6dbd6df 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 ``` ## 访问 @@ -58,11 +61,11 @@ gitbook serve - [x] 修改 Python 源码 - [ ] Python 内建对象 - [x] Python 对象初探 - - [ ] Python 整数对象 + - [x] Python 整数对象 - [ ] Python 字符串 对象 - - [ ] Python List 对象 - - [ ] Python Dict 对象 - - [ ] Python Set 对象 + - [x] Python List 对象 + - [x] Python Dict 对象 + - [x] Python Set 对象 - [ ] 实现简版 Python - [ ] Python 虚拟机 - [ ] Python 编译结果 @@ -74,3 +77,6 @@ gitbook serve - [ ] Python 模块加载机制 - [ ] Python 多线程机制 - [ ] Python 内存管理机制 + + + 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..cdc42ce 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。 - -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,键!=空,值=空(仅拆分),尚未插入到拆分表中。 +其中,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 的位置不能被重新使用,一旦发生碰撞,探针序列就无法知道这对键值对曾是活跃的键值对。 +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) @@ -56,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 */ @@ -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/list-object.md b/objects/list-object.md deleted file mode 100644 index 779bf7e..0000000 --- a/objects/list-object.md +++ /dev/null @@ -1 +0,0 @@ -# Python List 对象 diff --git a/objects/list-object/PyListStructure.png b/objects/list-object/PyListStructure.png new file mode 100644 index 0000000..9e357bd Binary files /dev/null and b/objects/list-object/PyListStructure.png differ diff --git a/objects/list-object/index.md b/objects/list-object/index.md new file mode 100644 index 0000000..76b6fb2 --- /dev/null +++ b/objects/list-object/index.md @@ -0,0 +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)` diff --git a/objects/long-object.md b/objects/long-object/index.md similarity index 76% rename from objects/long-object.md rename to objects/long-object/index.md index 1ffed04..3d86586 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) @@ -109,6 +107,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 ## 小整数对象 @@ -242,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 @@ -271,7 +371,7 @@ long_to_decimal_string_internal(PyObject *aa, } ``` -编译安装后进入python解释器输入如下代码 +编译安装后进入 python 解释器输入如下代码 ```python num = 9223372043297226753 @@ -287,13 +387,13 @@ print(num) 如下图所示 -![longobject storage](longobject_storage.png) +![longobject storage](long-storage.png) -注:这里的 30 是由 **PyLong_SHIFT** 决定的,64位系统中,**PyLong_SHIFT** 为30,否则 **PyLong_SHIFT** 为15 +注:这里的 30 是由 **PyLong_SHIFT** 决定的,64 位系统中,**PyLong_SHIFT** 为 30,否则 **PyLong_SHIFT** 为 15 ## 整数对象的数值操作 -可以看到整数对象的数值操作较多,由于篇幅限制无法一一分析,这里只分析整数的部分方法 +可以看到整数对象的数值操作较多,由于篇幅限制无法一一分析,这里只分析整数的部分操作 `源文件:`[Objects/longobject.c](https://github.com/python/cpython/blob/v3.7.0/Objects/longobject.c#L5341) @@ -340,13 +440,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 +520,16 @@ 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](long-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 +574,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,52 +588,12 @@ 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_sub 的示例图如下,注:PyLong_SHIFT 为 30 -加法运算函数 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 的过程大致如下图 - -![longobject x_sub](longobject_x_sub.png) +![longobject x_sub](long-x-sub.png) ### 整数相乘 @@ -514,7 +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 位数的一半。 +> 这样处理之后,简化为做三次乘法,并附带少量的加法操作和移位操作。 -`k_mul`函数是一种快速乘法[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/long-object/long-x-add.png b/objects/long-object/long-x-add.png new file mode 100644 index 0000000..63cb695 Binary files /dev/null and b/objects/long-object/long-x-add.png differ diff --git a/objects/long-object/long-x-sub.png b/objects/long-object/long-x-sub.png new file mode 100644 index 0000000..e500b12 Binary files /dev/null and b/objects/long-object/long-x-sub.png differ 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.md deleted file mode 100644 index cb084cc..0000000 --- a/objects/set-object.md +++ /dev/null @@ -1 +0,0 @@ -# Python Set 对象 diff --git a/objects/set-object/index.md b/objects/set-object/index.md new file mode 100644 index 0000000..74bbcd7 --- /dev/null +++ b/objects/set-object/index.md @@ -0,0 +1,593 @@ +# python 集合 + +set 是无序且不重复的集合,是可变的,通常用来从列表中删除重复项以及计算数学运算,如交集、并集、差分和对称差分等集合操作。set 支持 x in set, len(set),和 for x in set。作为一个无序的集合,set 不记录元素位置或者插入点。因此,sets 不支持 indexing, 或其它类序列的操作。 + +## python 集合概述 + +在 set 中,对应的 set 的值的存储是通过结构 setentry 来保存数据值的; + +`源文件:`[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 */ +} setentry; +``` + +key 就是保存的数据,hash 就是保存的数据的 hash,便于查找,set 也是基于 hash 表来实现。对应的 setentry 所对应的 set 的数据结构如下; + +`源文件:`[include/setobject.h](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Include/setobject.h#L42) + +```c +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 会根据保存的元素自动调整大小。相关的内存布局如下; + +![内存图片](set.png) + +## python 集合(set)示例 + +示例脚本如下: + +```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 反汇编获取该脚本的字节码; + +``` +python -m dis set_test.py +``` + +输出的字节码如下所示; + +```shell + 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](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();                    // 执行下一条指令 + } + +``` + +此时继续查看 PySet_New 函数的执行流程; + +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2286) + +```c +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 函数; + +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L2338) + +```c + +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 函数的执行过程; + +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L419) + +```c +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 中; + +`源文件:`[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) +{ + 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 初始化为空; + +```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 +``` + +![插入9](set-insert-nine.png) + +大致的 set 的插入过程执行完毕。 + +## set 的删除 + +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) +{ + 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 方法如下; + +`源文件:`[Objects/setobject.c](https://github.com/python/cpython/blob/1bf9cc509326bc42cd8cb1650eb9bf64550d817e/Objects/setobject.c#L447) + +```c + +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 方法; + +`源文件:`[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) +{ + 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 函数来实现; + +`源文件:`[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) +{ + 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 的值插入到新表中; + +`源文件:`[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) +{ + 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 的操作基本如上所述。 diff --git a/objects/set-object/set-insert-nine.png b/objects/set-object/set-insert-nine.png new file mode 100644 index 0000000..d08e521 Binary files /dev/null and b/objects/set-object/set-insert-nine.png differ diff --git a/objects/set-object/set-insert-one.png b/objects/set-object/set-insert-one.png new file mode 100644 index 0000000..15ae74d Binary files /dev/null and b/objects/set-object/set-insert-one.png differ diff --git a/objects/set-object/set-insert-two.png b/objects/set-object/set-insert-two.png new file mode 100644 index 0000000..6e90dab Binary files /dev/null and b/objects/set-object/set-insert-two.png differ diff --git a/objects/set-object/set.png b/objects/set-object/set.png new file mode 100644 index 0000000..ffd7628 Binary files /dev/null and b/objects/set-object/set.png differ 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/package-lock.json b/package-lock.json new file mode 100644 index 0000000..9bee6b2 --- /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.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", + "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" + } +} 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