├── README.md ├── scaffolds ├── draft.md ├── page.md └── post.md ├── source └── _posts │ ├── 命令行工具揭秘.md │ ├── 常用GitApi整理.md │ ├── 作用域是干什么用的.md │ ├── 自定义页面系统设计(一).md │ ├── 对前端路由选择的思考.md │ ├── 提升.md │ ├── 对象复制之深复制和浅复制.md │ ├── 自定义一个遍历器.md │ ├── axios和fetch实战分析.md │ ├── 树形数组递归优化算法.md │ ├── 闭包.md │ ├── React简析之实例化.md │ ├── 自定义页面系统设计(二).md │ ├── 监听者模式实战应用.md │ ├── 理解一发“请求跨域”.md │ ├── Promise介绍.md │ ├── React简析之节点挂载.md │ ├── Promise原理.md │ └── Promise实战.md ├── .gitignore ├── package.json ├── _config.yml └── yarn.lock /README.md: -------------------------------------------------------------------------------- 1 | https://github.com/func-star/blog/issues 2 | -------------------------------------------------------------------------------- /scaffolds/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | tags: 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | tags: 5 | --- 6 | -------------------------------------------------------------------------------- /source/_posts/命令行工具揭秘.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 命令行工具揭秘 3 | date: 2018-10-12 15:32:29 4 | tags: 5 | --- 6 | 7 | todo -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | .idea -------------------------------------------------------------------------------- /source/_posts/常用GitApi整理.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 常用Github Api整理 3 | date: 2018-10-13 14:36:19 4 | tags: 5 | --- 6 | 7 | * 获取指定仓库指定分支指定文件的原始内容(Raw) 8 | `https://raw.githubusercontent.com/用户名/仓库名/分支名/文件名` 9 | `https://raw.githubusercontent.com/capricornjs/capricorn-html-template/default/index.html` 10 | 11 | * 获取指定仓库的分支列表 12 | `https://api.github.com/repos/用户名/仓库名/branches` 13 | `https://api.github.com/repos/capricornjs/capricorn-html-template/branches` -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-site", 3 | "version": "0.0.0", 4 | "private": true, 5 | "hexo": { 6 | "version": "3.7.1" 7 | }, 8 | "scripts": { 9 | "publish": "hexo clean && hexo generate && hexo deploy" 10 | }, 11 | "dependencies": { 12 | "hexo": "^3.7.0", 13 | "hexo-deployer-git": "^0.3.1", 14 | "hexo-generator-archive": "^0.1.5", 15 | "hexo-generator-category": "^0.1.3", 16 | "hexo-generator-feed": "^1.2.2", 17 | "hexo-generator-index": "^0.2.1", 18 | "hexo-generator-tag": "^0.2.0", 19 | "hexo-renderer-ejs": "^0.3.1", 20 | "hexo-renderer-marked": "^0.3.2", 21 | "hexo-renderer-stylus": "^0.3.3", 22 | "hexo-server": "^0.3.1" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /source/_posts/作用域是干什么用的.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 作用域是干什么用的 3 | date: 2018-06-26 19:49:12 4 | tags: 5 | --- 6 | 7 | 在理解作用之前,我先介绍一下另外两个家伙---引擎和编译器。 8 | 9 | * 引擎:负责`javascript`整个执行的过程 10 | * 编译器:负责分词-解析词法-生成抽象语法树-生成可执行代码。`javascript`的代码片段编译发生在执行之前,大部分场景发生在代码执行前的几微秒。 11 | * 作用域:总的来讲就是统一收集维护标识符变量,并管理访问权限 12 | 13 | ### 下面针对一个示例代码来讲述三者之间微妙的关系: 14 | ```js 15 | var demo = 1; 16 | ``` 17 | 18 | 实际上这段代码可以分解为两步,第一步是:`var demo`,第二步是`demo = 1`。 19 | 当引擎执行到这段代码时,编译器首先会对这段代码进行如下处理: 20 | 21 | * 编译器会询问作用域是否已经存在一个叫`demo`的标识符(即变量)在同一个作用域中,若是,直接忽略这个声明,否则编译器会要求在当前作用域中声明一个叫`demo`的标识符,并分配存储内存。 22 | * 在编译器生成完可执行的代码之后,引擎开始处理`demo = 1`这个命令。 23 | 1. 首先引擎会询问当前作用域是否已经存在一个叫做`demo`的标识符(变量)。 24 | 2. 如果存在,引擎开始使用这个变量。 25 | 3. 如果不存在,引擎继续向上访问上级作用域,直到找到这个标识符为止。如果最终询问到全局作用域仍然未找到,则抛出一个异常(`ReferenceError`)。 26 | 27 | 总结:变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值。 28 | 29 | ### 接下来讲一下作用域嵌套: 30 | ```js 31 | var b = 1; 32 | function test() { 33 | console.log(b) 34 | } 35 | test(); 36 | ``` 37 | 38 | 当引擎执行到这一段代码时,会有以下几个步骤: 39 | * 引擎询问`test`的作用域是否存在`b`标识符 40 | * 结果在`test`的作用域中并不存在 41 | * 引擎接着询问`test`的上一级作用域(这里是全局作用域) 42 | * 结果找到了,开始使用`b` 43 | 44 | ### 总结下来,作用域就是一个集中管理变量,并且控制变量访问权限的枢纽。 45 | -------------------------------------------------------------------------------- /source/_posts/自定义页面系统设计(一).md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 自定义页面系统设计(一) 3 | date: 2018-10-15 19:56:56 4 | tags: 5 | --- 6 | 7 | ### 前言 8 | 9 | 在电商大环境里,活动页面的需求在前端领域是源源不断的,特别是在大促期间,就格外的多。 10 | 面对这堆枯燥无味还长的差不多的活动页面,前端🐶们往往是厌恶并且妈卖批的。 11 | 作为一个有梦想的搬砖的,我们当然是想办法解放我们的劳动力啦! 12 | 13 | ### 我们想要实现的究竟是个什么样的系统呢? 14 | 15 | 在回答这个问题之前,我们先来分析一下活动页面有哪些特征。 16 | * 活动页面的组成比较简单,通常由多个页面模块堆积组成,页面的布局不会很复杂 17 | * 模块的重用率很高,多个活动页面很大可能会用到同一个功能模块,只是数据会有不同 18 | * 绝大多数页面是一次性的,不需要后期维护 19 | * 活动页面的需求大,时间紧,运营说要就要 20 | * ... 21 | 22 | 逼逼了一大堆活动页面的特征,前端🐶心里想,这些简单的页面还让我来开发,简直就是浪费人才,要是运营自己能组装模块搭建页面就好了。 23 | 说了那么久终于进入正题了😄,对的!没错!我们就是要设计一个系统让运营来搭建活动页面,开发只需要负责开发功能模块。 24 | 25 | ### 开发过程中可能会遇到哪些问题 26 | 27 | 28 | #### 1.需要将页面拆分为基础模板和功能模块 29 | 30 | 页面由一个基础模板和多个功能模块组成,运营同学首先需要挑选一个页面的基础模板类型,然后再根据活动页面的功能组成,挑选功能模块来搭建页面。 31 | 32 | 举个例子:现在我们需要在微信容器内实现一个活动页面,这个页面涉及轮播图、页面导航和商品图墙三个功能,并且需要支持微信的一些功能。 33 | 这个场景下我们就需要一个微信基础模版,这个模版里面需要引入微信的一些`sdk`来支持微信独有的功能。并且我们需要实现三个功能模块,分别是轮播图模块、页面导航模块和商品图墙模块。 34 | 35 | #### 2.公共依赖抽离 36 | 一个页面由多个功能模块组成,而模块之间必然会存在公用的模块,比如`react`、`react-dom`等等。 37 | 那么如果每一个模块打包的时候都打把公用的三方包打进去,那么最后组装出来的页面就会包含很多重复的依赖包,体积过大就会影响页面性能。 38 | 39 | #### 3.模块通信 40 | 我们将页面拆分为多个模块之后,模块之间就是相互独立的了。我们需要通过另一种手段来实现模块之间的交互以及数据的通信。 41 | 42 | #### 4.模块信息配置 43 | 上面在分析特征的时候讲到模块重用的概率会很高,多个活动页面中可能存在同一个功能模块,只是数据会有些出入。 44 | 那么我们在实现公用功能模块的时候就需要考虑到如何通过配置信息生成一个模块?模块的配置信息存储在哪里?模块的后端数据请求怎么获取? 45 | 46 | #### 5.最终页面的拼装 47 | 解决完上述问题之后,我们就万事具备了哈,那么我们怎么将这些抽象的模块组装成一个可用的页面呢? 48 | 49 | 50 | 介绍完背景之后,让我们逐步来实现我们的构思吧!😁😁 51 | 52 | -------------------------------------------------------------------------------- /source/_posts/对前端路由选择的思考.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 对前端路由选择的思考 3 | date: 2018-08-09 20:11:01 4 | tags: 5 | --- 6 | 7 | ### 前言 8 | 随着 `SPA` 广泛应用在前端项目中,前端路由这个概念也伴随着火了起来。 9 | 这家伙目前主要是通过 `hash` 和 `hitory api` 这两个玩意实现,具体怎么实现的,后面稍微介绍一下。 10 | 11 | >本文不对这两个实现方案的好坏做过多评价,我依然觉得技术没有好坏,只有在具体的时间阶段和场景下,哪个更加合适一些。 12 | 13 | 接下来我来介绍一下这两个玩意的应用背景。 14 | 15 | ### `hash` 到 `history` 的变迁 16 | 在 `SPA` 单页面应用兴起的时候,大家都在寻找一个可以切换页面,且不会触发页面刷新的方案。 17 | 据我了解,`hash` 在被应用到前端路由之前,主要是被应用在页面锚点定位。 18 | 因为 `hash` 的`url` 信息携带主要依赖 `#`下面的字符,前端系统可以通过 `js` 解析页面路径信息来处理后续的逻辑,所以应该是当时的最优解决方案。 19 | 例如:`http://monajs.cn/docs/#home` 20 | 后来,`HTML5` 中新添加了 `History api` ,它支持切换和修改历史状态。主要通过 `back`、`forward`、`go` 21 | 三个方法,对应浏览器的前进,后退,跳转操。 22 | 修改历史状态包括了 `pushState`, `replaceState` 两个方法,这两个方法接收三个参数:`stateObj`,`title`,`url`。 23 | ```js 24 | history.pushState({name: 'yangxi'}, 'title', 'url') 25 | 26 | window.addEventListener('popstate', (e) => { 27 | if (e.state && e.state.name === 'yangxi') { 28 | return 29 | } 30 | //TODO 31 | }, false) 32 | ``` 33 | 从代码中可以看到,我们通过 `history` 做页面跳转的时候,可以携带信息,而且不像 `hash` 跳转那样只能携带有限的字符信息。`stateObj` 可以携带各种数据对象。 34 | >这是 `history api` 对前端路由切换的一次全新赋能。 35 | 36 | 另一方面,使用 `history api` 来设计前端路由,改善了之前 `#***` 的这种 `hash` 形式。一定程度上来讲美观了不少😄😄😄😄 37 | 38 | 以上特性,是我比较喜欢 `history api` 设计前端路由的重要理由,我自己也实现了一套基于 `history api` 的 [react-router](https://github.com/func-star/mo-react-router),有兴趣的朋友可以看一下。 39 | 40 | ### 前端路由实现思路 41 | 接下来我简单讲一下 `router` 的实现思路。 42 | 其实自己实现一个简单的 `router` 是比较简单的,我们只需要能监听到 `url` 的变化,然后对 `url` 进行一堆格式化分析,然后去匹配对应的页面实例。 43 | 44 | - `hash` 实现 45 | `hash` 实现路由是通过监听 `hashchange` 事件实现的,然后页面之间跳转则可以通过 `location.hash` 来做。 46 | - `history` 事件 47 | `history` 实现路由是通过监听 `popstate` 事件实现的,然后通过 `history api` 提供的 `pushState` 和 `replaceState` 来做页面的跳转和回退。 48 | 49 | >介绍的比较粗浅,仅代表个人的一些使用总结 50 | -------------------------------------------------------------------------------- /source/_posts/提升.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 提升 3 | date: 2018-06-26 19:50:18 4 | tags: 5 | --- 6 | 7 | 变量提升比较偏理论,可能会比较枯燥。不过了解原理能帮我们分析问题,解决问题。 8 | 9 | ### 在讲变量提升之前,我先简单的讲述一下函数作用域。 10 | ```js 11 | var a = 1; 12 | function test() { 13 | var b = 3; 14 | console.log( b ); // 3 15 | } 16 | test(); 17 | console.log( a ); // 1 18 | console.log(b); // 报错 19 | ``` 20 | 在这段代码中,在全局作用域中能访问到`a`和`test`却访问不到`b`,这是因为`test`在执行的时候生成了自己的函数作用域泡,只能在自身作用域内部能访问的到。 21 | 22 | ## 接下来直接从`demo`入手讲两个点: 23 | * 声明提升,赋值不会提升 24 | * 函数声明和变量声明都会被提升,但是函数声明优先与变量声明 25 | 26 | demo1: 27 | ```js 28 | console.log(a); // undefined 29 | var a = 1; 30 | ``` 31 | 很多人都理解这里能打印出`undefined`,而且都知道是因为变量声明被提升。但是为什么呢?? 32 | 33 | 我们在[作用域是干什么用的](https://github.com/func-star/scope/wiki/%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%98%AF%E5%B9%B2%E4%BB%80%E4%B9%88%E7%94%A8%E7%9A%84)中讲到,代码的执行分为两个阶段,第一步是由编译器解析生成一个可执行的代码段,再由引擎负责来执行代码。简单的讲`var a =1`是由`var a`和`a = 1`两步组成的。 34 | 知道这个点之后我们来分析一下上面`demo1`的代码的逻辑。在引擎接手来执行这段代码之前,编译器会先解析这段代码,在解析过程中,`var a`会由编译器负责去询问当前作用域,让作用域创建这个`a`标识符并进行管理维护。 35 | 因此在引擎开始执行这段代码的时候,`a`变量已经存在与当前作用域中,只是未进行赋值操作。 36 | 37 | demo2: 38 | ```js 39 | test(); 40 | function test() { 41 | console.log( a ); // undefined 42 | var a = 1; 43 | } 44 | ``` 45 | 在demo2中,有两个点: 46 | 1. `test`函数声明被提升 47 | 1. 在`test`函数作用域中`a`变量声明也被提升 48 | 49 | demo3: 50 | ```js 51 | test(); // 1 52 | var test; 53 | function test() { 54 | console.log(1); 55 | } 56 | foo = function() { 57 | console.log(2); 58 | }; 59 | ``` 60 | 观察`demo3`中的代码,很多人可能以为`var test`在编译时已经被执行,所以在执行`test()`的时候应该是报`TypeError`,因为`test`当前是`undefined`,并未进行赋值操作。但是实际上却输出了结果:`1`。 61 | 因为函数声明会优先于变量声明,在编译器执行到`var test`时,`function test(){...}`已经被当前作用域所创建,因此`var test`这句代码被忽略,从而在访问`test()`的时候输出了`1` 。 62 | 63 | demo4: 64 | ```js 65 | test(); // 2 66 | var test; 67 | function test() { 68 | console.log(1); 69 | } 70 | function test() { 71 | console.log(2); 72 | } 73 | ``` 74 | 上述代码说明函数声明是可以被覆盖的。 75 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: 杨玺的博客 7 | subtitle: 8 | description: 杨玺的博客 9 | keywords: blog 10 | author: yangxi 11 | language: zh-CN 12 | timezone: 13 | 14 | # URL 15 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 16 | url: https://monajs.github.io 17 | root: / 18 | permalink: :year/:month/:day/:title/ 19 | permalink_defaults: 20 | 21 | # Directory 22 | source_dir: source 23 | public_dir: public 24 | tag_dir: tags 25 | archive_dir: archives 26 | category_dir: categories 27 | code_dir: downloads/code 28 | i18n_dir: :lang 29 | skip_render: 30 | 31 | # Writing 32 | new_post_name: :title.md # File name of new posts 33 | default_layout: post 34 | titlecase: false # Transform title into titlecase 35 | external_link: true # Open external links in new tab 36 | filename_case: 0 37 | render_drafts: false 38 | post_asset_folder: false 39 | relative_link: false 40 | future: true 41 | highlight: 42 | enable: false 43 | line_number: false 44 | auto_detect: false 45 | tab_replace: 46 | 47 | # Home page setting 48 | # path: Root path for your blogs index page. (default = '') 49 | # per_page: Posts displayed per page. (0 = disable pagination) 50 | # order_by: Posts order. (Order by date descending by default) 51 | index_generator: 52 | path: '' 53 | per_page: 0 54 | order_by: -date 55 | 56 | # Category & Tag 57 | default_category: uncategorized 58 | category_map: 59 | tag_map: 60 | 61 | # Date / Time format 62 | ## Hexo uses Moment.js to parse and display date 63 | ## You can customize the date format as defined in 64 | ## http://momentjs.com/docs/#/displaying/format/ 65 | date_format: YYYY-MM-DD 66 | time_format: HH:mm:ss 67 | 68 | # Pagination 69 | ## Set per_page to 0 to disable pagination 70 | per_page: 0 71 | pagination_dir: page 72 | 73 | # Extensions 74 | ## Plugins: https://hexo.io/plugins/ 75 | ## Themes: https://hexo.io/themes/ 76 | theme: hexo-theme-clean-blog 77 | 78 | # Deployment 79 | ## Docs: https://hexo.io/docs/deployment.html 80 | deploy: 81 | type: git 82 | repository: https://github.com/monajs/monajs.github.io.git 83 | branch: master 84 | -------------------------------------------------------------------------------- /source/_posts/对象复制之深复制和浅复制.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 对象复制之深复制和浅复制 3 | date: 2018-06-26 16:44:31 4 | tags: 5 | --- 6 | 7 | 首先我们先来了解一下深复制和浅复制之间的区别。 8 | 9 | 从字面上来看,我们会觉得浅复制就是非彻底的复制对象,而深复制即彻底的复制对象,新对象将跟原来的对象毫无关联。 10 | 实际上也差不多,浅复制只复制对象第一层的属性,而深复制则递归复制了所有层级的属性。 11 | 12 | 下面通过`demo`来分析一下 13 | ```js 14 | var origin = {a:1, b: {c:2}}; 15 | var origin1 = {a:1, b: [1,2,3]}; 16 | var obj = cloneObj(origin); 17 | var obj1 = cloneObj(origin1); 18 | 19 | function cloneObj(obj) { 20 | if(typeof obj !== 'object'){ 21 | return; 22 | } 23 | var res = {}; 24 | for(var i in obj) { 25 | if(obj.hasOwnProperty(i)){ 26 | res[i] = obj[i] 27 | } 28 | } 29 | return res; 30 | } 31 | 32 | console.log(obj); // {a:1, b: {c:2}}; 33 | console.log(obj1); // {a:1, b:[1,2,3]}; 34 | ``` 35 | 上面是一段简单的浅复制的代码,代码中`cloneObj`函数只对原对象的第一层做了赋值操作。这样一来,如果第一层属性中如果有对象,就会出现问题,如下代码所示: 36 | ```js 37 | obj.b.c = 5; 38 | console.log(origin.b.c); // 5 39 | obj1.b[0] = 5; 40 | console.log(origin1.b[0]); // 5 41 | ``` 42 | ### 可以看出,对于字符串类型,浅复制是对值的复制,但是对于对象来说,浅复制是对对象地址的复制,`obj`和`origin`指向的是同一块内存地址。 43 | 44 | 而对于深复制来讲,实际上就是用递归算法遍历原对象所有层级的属性,并复制到一个新生成的对象中,来看一下下面的`demo`: 45 | ```js 46 | var origin = {a:1, b: {c:2}}; 47 | var origin1 = {a:1, b: [1,2]}; 48 | var obj = deepCopy(origin); 49 | var obj1 = deepCopy(origin1); 50 | 51 | function deepCopy(obj) { 52 | if(typeof obj !== 'object') { 53 | return ; 54 | } 55 | var res; 56 | if(Object.prototype.toString.call(obj) === '[object Array]') { 57 | res = []; 58 | }else { 59 | res = {}; 60 | } 61 | 62 | for(var i in obj) { 63 | if(typeof obj[i] === 'object') { 64 | res[i] = deepCopy(obj[i]); 65 | }else { 66 | res[i] = obj[i]; 67 | } 68 | } 69 | return res; 70 | } 71 | 72 | console.log(obj); 73 | console.log(obj1); 74 | ``` 75 | 上述深度复制的代码考虑了数组和对象两种引用类型数据结构,接下来我们来测试一下: 76 | ```js 77 | obj.b.c = 5; 78 | console.log(origin.b.c); // 2 79 | obj1.b[0] = 5; 80 | console.log(origin1.b[0]); // 1 81 | ``` 82 | 83 | 然而在实际应用场景中,浅复制的场景要比深复制更为普遍,所以在 ES6 中定义了`Object.assign(..)`方法来实现浅复制。 84 | ```js 85 | var origin = {a:1, b: {c:2}}; 86 | var obj = Object.assign({}, origin); 87 | console.log(obj); // {a:1, b: {c:2}}; 88 | obj.b.c = 5; 89 | console.log(origin.b.c); // 5 90 | ``` 91 | `Object.assign` 会遍历一个或多个源对象的所有可枚举`(enumerable)`的自有键,并把它们复制(使用 = 操作符赋值)到目标对象,最后返回目标对象。 92 | -------------------------------------------------------------------------------- /source/_posts/自定义一个遍历器.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 自定义一个遍历器 3 | date: 2018-06-26 19:48:07 4 | tags: 5 | --- 6 | 7 | 在 es5 之前,遍历一个数组我们肯定会用标准的`for`循环。 8 | 9 | ```js 10 | var myArray = ['a', 'b', 'c']; 11 | for (var i = 0, l = myArray.length; i < l; i++) { 12 | console.log(myArray[i]); 13 | } 14 | // a, b, c 15 | ``` 16 | 实际上这里遍历的并不是数组的每一项值,而是数组的下标,通过下标指针来访问数组的值,如`myArray[i]`。 17 | 18 | 同样 `for..in` 遍历对象也是遍历对象的属性,无法直接获取属性值,需要通过手动去获取。 19 | 20 | 那么如何直接去遍历属性值呢?ES6 增加了一种用来遍历数组的 `for..of` 循环语法(如果对象本身定义了迭代器的话也可以遍历对象): 21 | ```js 22 | var myArray = ['a', 'b', 'c']; 23 | for (var v of myArray) { 24 | console.log( v ); 25 | } 26 | // a, b, c 27 | ``` 28 | `for..of`首先会向`myArray`请求一个迭代器对象,然后通过迭代器对象的`next()`方法来遍历访问所有值。 29 | 因为数组有内置的`@@itrator`,所以数组可以使用`for..of`,来看一下内部具体是怎么运行的: 30 | 31 | ```js 32 | var myArray = ['a', 'b', 'c']; 33 | var item = myArray[Symbol.iterator](); 34 | item.next(); // {value: "a", done: false} 35 | item.next(); // {value: "b", done: false} 36 | item.next(); // {value: "c", done: false} 37 | item.next(); // {value: undefined, done: true} 38 | ``` 39 | 我们可以理解为遍历器对象本质上,就是一个指针对象。 40 | 在执行遍历之前,我们先创建一个指针对象并指向数组的初始位置,在第一次调用`next()`的时候,指针往下移动一位,指向数组的第一个成员,并返回对应的`value`和是否已经遍历完毕。一直调用`next()`知道遍历完数组所有的成员,即`done: false`。 41 | 42 | ES6 规定,默认的 `Iterator` 接口部署在数据结构的`Symbol.iterator`属性,或者说,一个数据结构只要具有`Symbol.iterator`属性,就可以认为是“可遍历的”(`iterable`)。`Symbol.iterator`属性本身是一个函数,就是当前数据结构默认的遍历器生成函数。 43 | 44 | ### 接下来用进入主题,用几个例子来自定义一个遍历器。 45 | 46 | ```js 47 | var myObject = { a: 2,b: 3 }; 48 | 49 | for (var v of myObject) { 50 | console.log( v ); 51 | } 52 | // TypeError: myObject is not iterable 53 | ``` 54 | 当对一个对象进行遍历的时候,会抛出一个错误,因为对象内部没有定义`Symbol.iterator`返回函数。 55 | 当然我们可以自定义一个`@@iterator`来支持对象遍历,`@@iterator` 本身并不是一个迭代器对象,而是一个返回迭代器对象的函数。 56 | 57 | ```js 58 | var myObject = { a: 2,b: 3 }; 59 | 60 | Object.defineProperty(myObject, Symbol.iterator, { 61 | value: function() { 62 | var ins = this, 63 | index = 0, 64 | keys = Object.keys(ins); 65 | return { 66 | next: function () { 67 | return { 68 | value: ins[keys[index++]], 69 | done: index>keys.length 70 | } 71 | } 72 | } 73 | } 74 | }) 75 | for (var v of myObject) { 76 | console.log( v ); 77 | } 78 | // 2, 3 79 | ``` 80 | 81 | 自定义遍历器,我们相当于控制了`next()`的返回值(例如改变返回的值),通过这一个特性,可以实现很多个性化的逻辑。 82 | ```js 83 | var myObject = { a: 2,b: 3 }; 84 | 85 | Object.defineProperty(myObject, Symbol.iterator, { 86 | value: function() { 87 | var ins = this, 88 | index = 0, 89 | keys = Object.keys(ins); 90 | return { 91 | next: function () { 92 | return { 93 | value: ins[keys[index++]]*2, 94 | done: index>keys.length 95 | } 96 | } 97 | } 98 | } 99 | }) 100 | for (var v of myObject) { 101 | console.log( v ); 102 | } 103 | // 4, 6 104 | ``` 105 | -------------------------------------------------------------------------------- /source/_posts/axios和fetch实战分析.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: axios 和 fetch 实战分析 3 | date: 2018-08-08 20:09:42 4 | tags: 5 | --- 6 | 7 | ### 前言 8 | 趁着搭建公司新版 `react` 移动端脚手架的机会,对 `http-client` 库细致了解了一番。`axios` 和 `fetch`是目前比较火热的两款产品,这里就我了解到的一些信息记录一下。 9 | 10 | ### `fetch api` 使用总结 11 | 之前我在 PC 端项目中选择的是 `fetch api`,使用了将近两年左右,这里我将个人的使用体验分享一下。 12 | 13 | - `fetch` 默认不会携带 `cookie`, 我们需要手动设置 `credentials` 来支持 `cookie` 携带给服务端。 14 | - `fetch` 的 `response` 返回状态码比较特殊,它把`400`、`500`的返回码都当成成功的返回,我们在使用的时候可能需要特地封装一下。 15 | - `fetch` 没办法取消本次请求,只要你发送了本次请求,后续的情况都是不可控的。 16 | - 另外,我们知道 `fetch` 作为 `AJAX` 的一个替代品,它并不是基于 `XHR` 实现的,所以它并不能检测到请求的进度。 17 | 18 | 可能或许大概你会拿它和 `$.ajax`、`axios` 这类封装的比较完善的库做对比,而且开始吐槽,这东西怎么哪哪都不如 `axios` 。 19 | 这里我们先要确定一下 `fetch api` 的定位,它是一个更加偏底层的库,提供了丰富的 `API` 给开发者调用,可以支持很多的底层功能,但是可能找不到基于场景封装好的功能。 20 | 因此,我们在选择 `fetch` 的时候需要考虑我们是不是有这么复杂的需求需要通过 `fetch api` 来支持,用 `axios` 是不是会更省事? 21 | 22 | 上述介绍了一大堆的 `fetch api` 的缺点,可能大家会认为我对 `fetch api` 有什么偏见... 哈哈😄。实际上我近两年的 `http-client` 库选择的都是 `fetch api`。 23 | 还是那句话,没有最好的产品,只有最适合的产品。如果某个产品你用的习惯了,你就咋看咋顺眼。 24 | 25 | ### `axios` 使用总结 26 | 从去年下半年开始,我开始在线上移动端使用 `axios` 。接下来讲一下我个人的使用情况。 27 | 28 | 刚开始用的时候我也是看了很多的文档资料,毕竟网上把这东西夸的天花乱坠的,到底这东西魅力在哪里,得自己试试才知道呀。 29 | 30 | 这里先介绍一下我之前对 `axios` 做的分析,具体是不是真的有那么大魅力,我们后面用场景验证。 31 | - `axios` 支持设置全局默认配置,比如项目中基本不会变的根域名、`headers`配置这些,我们都可以初始化设置一发。 32 | - `axios` 拦截器也是一个比较好用的功能,它允许在发 `request` 之前和接收 `response` 之前进行自己的一些逻辑处理。 33 | - 还有一点比较重要的是,这家伙支持请求取消呀,这能一定程度的减少网络请求资源浪费。 34 | 35 | 以上三点是我比较 care 的特性,其他的我就不罗列介绍了。 36 | 下面我们来看一下怎么封一个 `axios` 类(临时写的一个思路,未测试),让它帮我们的业务更好的赋能。 37 | ```js 38 | import axios from 'axios' 39 | import Evnets from 'mona-events' 40 | 41 | const CancelToken = axios.CancelToken 42 | 43 | class Ajax extends Evnets { 44 | constructor(props) { 45 | super(props) 46 | axios.default.baseURL = 'https://api.monajs.cn' 47 | this.filter 48 | } 49 | 50 | get(url, params = {}, canCancel = false, cancelOption) { 51 | if (canCancel) { 52 | params.cancelToken = new CancelToken(function executor(c) { 53 | // executor 函数接收一个 cancel 函数作为参数 54 | cancelOption = c; 55 | }) 56 | } 57 | return axios.get(url, params); 58 | } 59 | 60 | post(url, params = {}, canCancel = false, cancelOption) { 61 | if (canCancel) { 62 | params.cancelToken = new CancelToken(function executor(c) { 63 | // executor 函数接收一个 cancel 函数作为参数 64 | cancelOption = c; 65 | }) 66 | } 67 | return axios.post(url, params) 68 | } 69 | 70 | filter() { 71 | axios.interceptors.request.use(config => { 72 | // 在发送请求之前做些什么 73 | return config; 74 | }, error => { 75 | // 对请求错误做些什么 76 | return Promise.reject(error); 77 | }); 78 | axios.interceptors.response.use(response => { 79 | // 对响应数据做点什么 80 | return response; 81 | }, error => { 82 | // 对响应错误做点什么 83 | return Promise.reject(error); 84 | }) 85 | } 86 | } 87 | ``` 88 | 89 | 上面基本上阐述了两个事情: 90 | - `axios` 配合我们的业务场景使用,例如结合服务端的业务返回码,接口请求异常,做统一逻辑处理,规避掉很多冗余代码。 91 | - `axios` 类初始化一些配置信息,在真实使用的时候其他的接口服务层类可以继承这个类,可以改写覆盖这些配置信息,也可以使用默认值。 92 | - `axios` 类配合 `Events` 类完成服务接口监听者模式,更高效的实现接口数据分发,减少掉代码中的回调函数传递。(这个点后续专门开一篇文章详细阐述其使用魅力) 93 | 94 | 总结下来我的观点是选择哪个 `http-client` 库进行业务开发取决于实际场景,在移动端开发,我个人比较偏向于 `axios` 。它能够帮我们较少成本的上手使用。 95 | -------------------------------------------------------------------------------- /source/_posts/树形数组递归优化算法.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 树形数组递归优化算法 3 | date: 2018-06-08 20:05:43 4 | tags: 5 | --- 6 | 7 | 最近在项目中遇到的场景,在这分享一下。 8 | 9 | 通常来讲,对一个树形数组做处理,特别是层级未知的数据结构,第一想法肯定是遍历。在不考虑性能的情况下,基本上都能解决。 10 | 11 | 下面来个例子: 12 | 数据结构: 13 | ```js 14 | let data = [{ 15 | id: 1, 16 | name: 'a', 17 | children: [ 18 | { id: 11, name: 'aa' }, 19 | { 20 | id: 12, 21 | name: 'ab', 22 | children: [ 23 | { id: 121, name: 'aba' }, 24 | { id: 122, name: 'abb' } 25 | ] 26 | }, 27 | { id: 13, name: 'ac' } 28 | ] 29 | }, 30 | { 31 | id: 2, 32 | name: 'b', 33 | children: [ 34 | { id: 21, name; 'ba' }, 35 | { id: 22, name; 'bb' } 36 | ] 37 | }, 38 | { id: 3, name; 'c' } 39 | ]; 40 | ``` 41 | 现在我们先用大家熟悉的递归来实现一遍。 42 | 43 | ```js 44 | let test = (() => { 45 | let res = ''; 46 | return inner = (data, id) => { 47 | if (!data || data.length === 0) { 48 | return 49 | } 50 | 51 | data.forEach(v => { 52 | if (v.id === id) { 53 | res = v.name 54 | } 55 | 56 | if (v.children && v.children.length > 0) { 57 | inner(v.children, id) 58 | } 59 | }) 60 | return res; 61 | } 62 | })() 63 | 64 | let val = test(data, 123); 65 | console.log(val); 66 | ``` 67 | 68 | 实现完成之后我们会思考怎么才能把它的性能提高,特别是在树层级特别深的场景下,递归的性能还是比较难以接受的。 69 | 70 | ## 优化方案: 71 | 针对二叉树遍历,有深度优先和广度优先两种通用解决方案,我们可以根据数据结构的广度和深度选择最优的解决方案。虽然在前端日常开发中,很少会用到算法,但是这种性能优化的方案还是可以借鉴的。 72 | 73 | ### 广度优先 74 | 根据广度优先的思路来看一下代码实现。 75 | ```js 76 | let test2 = (() => { 77 | let res = ''; 78 | return inner = (data, id) => { 79 | if (!data || data.length === 0) { 80 | return 81 | } 82 | let stark = []; // 初始化一个数据栈 83 | // 将第一层数据压入栈 84 | data.forEach(v => { 85 | stark.push(v); 86 | }) 87 | 88 | while (stark.length > 0) { 89 | let item = stark.shift(); 90 | if (item.id === id) { 91 | res = item.name; 92 | } 93 | if (item.children && item.children.length > 0) { 94 | stark = stark.concat(item.children) 95 | } 96 | } 97 | return res; 98 | } 99 | })() 100 | 101 | let val = test2(data, 123); 102 | console.log(val); 103 | ``` 104 | 105 | ### 深度优先 106 | 根据深度优先的思路来看一下代码实现。 107 | ```js 108 | let test3 = (() => { 109 | let res = ''; 110 | return inner = (data, id) => { 111 | if (!data || data.length === 0) { 112 | return 113 | } 114 | 115 | let stark = []; // 初始化一个数据栈 116 | // 将第一层数据压入栈 117 | data.forEach(v => { 118 | stark.push(v); 119 | }) 120 | 121 | while (stark.length > 0) { 122 | let item = stark.shift(); 123 | if (item.id === id) { 124 | res = item.name; 125 | } 126 | if (item.children && item.children.length > 0) { 127 | stark = item.children.concat(stark); 128 | } 129 | } 130 | return res; 131 | } 132 | })() 133 | 134 | let val = test3(data, 123); 135 | console.log(val); 136 | ``` 137 | 138 | -------------------------------------------------------------------------------- /source/_posts/闭包.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 闭包 3 | date: 2018-06-26 20:00:31 4 | tags: 5 | --- 6 | 7 | 闭包一直以一种神秘的姿态出现在前端领域中。大家都知道这东西在代码中无处不在,可又很难表达出这东西是什么干嘛用的。接下来我来简单聊一下我对闭包的理解,篇幅不会太长,意在让大家理解。 8 | 9 | 对闭包的使用释义,网上一搜一大堆,主要可以概括为以下几种: 10 | * 内部作用域访问到了上级作用域的变量 11 | * 内部函数被传递到所在词法作用域以外来调用 12 | * LIFE模式(立即执行函数) 13 | * 模块模式 14 | 15 | 这些都是闭包的使用场景,由此可见闭包的功能真的很强,而且细微实用。 16 | 17 | 在正式开始讲闭包之前,我先来回顾以下引擎这个东西,在[作用域是干什么用的](https://github.com/func-star/scope/wiki/%E4%BD%9C%E7%94%A8%E5%9F%9F%E6%98%AF%E5%B9%B2%E4%BB%80%E4%B9%88%E7%94%A8%E7%9A%84)中介绍过引擎负责执行经由编译器解析后生成的可执行的代码段。 18 | 这里再补充一点,引擎还拥有一垃圾回收机制,当作用域为标识符分配的内存空间不再被使用的时候,就会由垃圾回收器负责将其回收并释放该内存。 19 | 20 | ### 下面来看一段代码来给出我对闭包的理解定义: 21 | ```js 22 | function test() { 23 | var a = 1; 24 | function inner() { 25 | console.log(a); 26 | } 27 | return inner; 28 | } 29 | var fn = test(); 30 | fn(); // 1 31 | ``` 32 | 当`test()`执行结束之后,我们可能会以为整个`test()`的内部作用域都被销毁掉,因为引擎的垃圾回收器会负责释放不再被使用的内存。然后实际上`inner`被正常执行了,并且访问到了`a`。 33 | 34 | 这个现象的背后就是因为闭包在阻止着这次垃圾回收。我们观察代码可以看出`inner`函数在使用着`a`标识符(变量),而`a`变量却被定义在了其上级作用域中,因此在`inner`函数执行之前,引擎识别到`a`留着还有用,所以不能清理`a`所在的作用域,这就是闭包的一种现象。 35 | 36 | 现在我们来归纳以下,内部作用域保持着对外部作用域的引用,这个引用其实就是闭包。我个人理解闭包其实就是一个作用域的集合,它包含自身的词法作用域和对执行过程中用得到的作用域。在上面的代码中,`inner()`一直保持有对`test()`整个作用域的引用。 37 | 38 | ### 希望上面的解释可以为你解惑,下面来看一个用烂了的例子: 39 | 40 | ```js 41 | for (var i=1; i<=5; i++) { 42 | setTimeout( function test() { 43 | console.log(i); 44 | }, i*1000 ); 45 | } 46 | ``` 47 | 这个`demo`很多人肯定已经看很多遍了, 知道会输出5个`6`。这里我结合上面的理论来阐述一遍。 48 | 49 | 这里先重温一下两个点: 50 | 1. 词法作用域,引擎会先向当前作用域询问变量是否存在,如果找不到就往上级找。 51 | 2. `setTimeout`是一个异步方法,他的回掉函数并不会立马被添加到主进程中来执行。 52 | 53 | 下面我来翻译一下上面的代码: 54 | ```js 55 | var i = 1; 56 | setTimeout( function test() { 57 | console.log(i); 58 | }, 1000 ); 59 | 60 | i = 2; 61 | setTimeout( function test() { 62 | console.log(i); 63 | }, 2000 ); 64 | 65 | i = 3; 66 | setTimeout( function test() { 67 | console.log(i); 68 | }, 3000 ); 69 | 70 | i = 4; 71 | setTimeout( function test() { 72 | console.log(i); 73 | }, 4000 ); 74 | 75 | i = 5; 76 | setTimeout( function test() { 77 | console.log(i); 78 | }, 5000 ); 79 | 80 | i = 6 81 | ``` 82 | 实际上,`setTimeout`的回调函数`test`访问的都是同一个共享的作用域(这里其实就是全局作用域)。而且`setTimeout`是一个异步的执行过程,因此等`test`执行到的时候`i`早已经被赋值为`6`。所以会输出5个`6`。 83 | 84 | 其实想要让它输出`12345`,大家肯定也都会,我们只需要用LIFE(立即执行函数)包一下这个`for`循环中的执行体,并将即时的状态i记录在内部作用域中,那当`test`执行的时候就能访问到不同的`i`了,如下代码: 85 | ```js 86 | for (var i=1; i<=5; i++) { 87 | (function(j){ 88 | setTimeout( function test() { 89 | console.log(j); 90 | }, j*1000 ); 91 | }(i)) 92 | } 93 | ``` 94 | 95 | 下面我们也用代码来解释这个过程: 96 | ```js 97 | var i = 1; 98 | (function(){ 99 | var j = i 100 | setTimeout( function test() { 101 | console.log(j); 102 | }, 1000 ); 103 | }()) 104 | 105 | i = 2; 106 | (function(){ 107 | var j = i 108 | setTimeout( function test() { 109 | console.log(j); 110 | }, 2000 ); 111 | }()) 112 | 113 | i = 3; 114 | (function(){ 115 | var j = i 116 | setTimeout( function test() { 117 | console.log(j); 118 | }, 3000 ); 119 | }()) 120 | 121 | i = 4; 122 | (function(){ 123 | var j = i 124 | setTimeout( function test() { 125 | console.log(j); 126 | }, 4000 ); 127 | }()) 128 | 129 | i = 5; 130 | (function(){ 131 | var j = i 132 | setTimeout( function test() { 133 | console.log(j); 134 | }, 5000 ); 135 | }()) 136 | 137 | i = 6 138 | ``` 139 | 140 | 从上述代码可以看到实际上`test()`在执行的时候访问的标识符`j`已经是当前作用域的上级作用域私有的,不再是共享同一个作用域。 141 | 142 | 另一种方法当然是用`let`来生成块级作用域,道理都差不多,不再介绍。 143 | -------------------------------------------------------------------------------- /source/_posts/React简析之实例化.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: React简析之实例化 3 | date: 2018-07-16 20:07:19 4 | tags: 5 | --- 6 | 7 | ### 概述 8 | 这是一个 `React` 原理解读的系列,将带你一步步实现一个简化版的 `React`。不多说废话,现在开始!!! 9 | 代码地址:[v1.0](https://github.com/func-star/mo-react/tree/v1.0) 10 | 11 | 12 | ### `React`的主入口 13 | ```js 14 | import { render } from 'react-dom' 15 | ... 16 | render(123, document.getElementById('appWrapper')) 17 | ``` 18 | 这行代码大家肯定都非常熟悉,`render()` 函数是 `React` 最基本的方法,是整个 `React` 执行的开端。 19 | 我们可以看到 `render` 接收两个参数,一个 `dom` 模版,另一个是模版插入的位置,那么 `render()` 具体做了哪些事情呢? 20 | ```js 21 | // ReactMount.js 22 | 23 | import ReactInstantiate from './ReactInstantiate' 24 | 25 | class ReactMount { 26 | render(nextElement, container, callback) { 27 | // 节点实例化 28 | let instance = new ReactInstantiate(nextElement, null, true) 29 | console.log(instance) 30 | // 节点挂载 31 | let node = instance.mount(null, true) 32 | container.appendChild(node) 33 | } 34 | } 35 | 36 | export default new ReactMount 37 | ``` 38 | 39 | 从代码中我们可以看到 `render()` 先会将接收到的 `dom` 结构进行一个实例化的过程,并生成一个实例对象数据结构`instance`。 40 | 接着是对实例对象进行挂载,这一节主要是将 `React` 节点解析成浏览器原生节点,添加合成事件、绑定可识别属性等。这一块我们在下一节会进行讲解。 41 | 再接着就是节点插入。 42 | 43 | ### 下面我们来介绍一下节点实例化到底干了哪些事情 44 | 45 | 在讲实例化之前,首先我们先了解一下 `React` 节点分为4种节点类型,分别是空节点、文本节点、原生节点(浏览器节点)以及 `React` 节点。 46 | 根据这个我们先来定义一个数据字典,如下: 47 | ```js 48 | // constant.js 49 | 50 | export default { 51 | VERSION: '0.0.1', 52 | REACT_NODE: 'reactNode', 53 | EMPTY_NODE: 'emptyNode', 54 | TEXT_NODE: 'textNode', 55 | NATIVE_NODE: 'nativeNode' 56 | } 57 | 58 | ``` 59 | 实际上,每一个节点实例都会存储节点的一些信息,包含节点类型、节点的唯一key、节点的dom数据、子节点实例数组。 60 | ```js 61 | // ReactInstantiate.js 62 | 63 | import reactDom from './ReactDom' 64 | import reactEvents from './ReactEvents' 65 | import ReactUpdater from './ReactUpdater' 66 | import Constant from '../constant' 67 | import Util from '../util' 68 | import ValueData from '../data' 69 | 70 | export default class ReactInstantiate { 71 | constructor(element, key) { 72 | // react节点 73 | this.currentElement = element 74 | // 节点唯一key 75 | this.key = key 76 | // 节点类型 77 | this.nodeType = reactDom.getElementType(element) 78 | // 节点实例化数据结构 79 | this.childrenInstance = this.instanceChildren() 80 | } 81 | 82 | // 递归实例化所有节点,忽略react组件节点 83 | instanceChildren() { 84 | if (this.nodeType === Constant.EMPTY_NODE || this.nodeType === Constant.TEXT_NODE || !this.currentElement.props || !this.currentElement.props.children) { 85 | return 86 | } 87 | 88 | let child = Util.toArray(this.currentElement.props.children) 89 | let childrenInstance = [] 90 | // 为每一个节点添加唯一key 91 | child.forEach((v, i) => { 92 | let key = null 93 | if (null !== v && typeof v === 'object' && v.key) { 94 | key = '__@_' + v.key 95 | } 96 | if (Util.isArray(v)) { 97 | let c = [] 98 | v.forEach((item, index) => { 99 | let itemKey = '__$_' + i + '_' + index 100 | if (null !== v && typeof v === 'object') { 101 | if (!item.key) { 102 | console.error(ValueData.keyNeedMsg) 103 | } else { 104 | itemKey = '__@_' + i + '_' + item.key 105 | } 106 | } 107 | c.push(new ReactInstantiate(item, itemKey)) 108 | }) 109 | childrenInstance.push(c) 110 | } else { 111 | childrenInstance.push(new ReactInstantiate(v, key)) 112 | } 113 | }) 114 | return childrenInstance 115 | } 116 | } 117 | ``` 118 | 119 | 至此,节点的实例化过程已经完成,我们得到一个数据装载完整的`react`实例数据。 120 | 这边介绍的代码并不完整,可以前往[v1.0](https://github.com/func-star/mo-react/tree/v1.0),clone下来本地跑一遍。 121 | -------------------------------------------------------------------------------- /source/_posts/自定义页面系统设计(二).md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 自定义页面系统设计(二) 3 | date: 2018-10-16 19:39:37 4 | tags: 5 | --- 6 | 7 | 接着[上一节](https://monajs.github.io/2018/10/15/%E8%87%AA%E5%AE%9A%E4%B9%89%E9%A1%B5%E9%9D%A2%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1%EF%BC%88%E4%B8%80%EF%BC%89/)讲,这个章节主要会讲解如何解决下面几个点: 8 | 9 | * 需要将页面拆分为基础模板和功能模块 10 | * 公共依赖抽离 11 | * 模块通信 12 | 13 | > 建议按照顺序来阅读哟~ 14 | 15 | 16 | ### 将页面拆分为基础模板和功能模块 17 | 18 | [上一节](https://monajs.github.io/2018/10/15/%E8%87%AA%E5%AE%9A%E4%B9%89%E9%A1%B5%E9%9D%A2%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1%EF%BC%88%E4%B8%80%EF%BC%89/)讲到我们想要实现的是一个功能模块可以重复使用的系统,运营可以选择一个基础页面模版,然后自由的选择多个功能模块来搭建页面(可视化界面的设计后续会作介绍,这里先不涉及)。 19 | 20 | 基于这个点我们需要准备好以下几点: 21 | 22 | #### 1. 统一维护一个基础页面模板集合,开发同学可以方便的添加和修改 23 | 24 | 默认模版我们维护在[capricorn-html-template](https://github.com/capricornjs/capricorn-html-template)项目的`default`分支下,如果有需要新增一份模版,可以在该项目里添加分支并创建模板。 25 | 26 | 27 | #### 2.统一维护一个功能模块初始化项目集合,保证所有开发出来的功能模块格式统一,方便后期的维护 28 | 29 | 默认初始化项目我们维护在[capricorn-module-template](https://github.com/capricornjs/capricorn-module-template)的`default`分支下,如果有需要新增一份初始化代码,可以在该项目里添加分支并创建。 30 | 31 | #### 3.开发一个命令行工具,可以方便快捷的初始化一个功能模块项目 32 | 33 | * 安装 34 | ```bash 35 | npm i capricorn-cli -g 36 | ``` 37 | 38 | * 开始使用 39 | ```bash 40 | capricorn init 41 | ``` 42 | 43 | 现在我们可以来试一下了哈😁嘿嘿~ 44 | 我们通过`capricorn init`出来的项目,只需要`npm i`安装完依赖之后,`npm start`就可以启动项目了哈~ 45 | 接下来我们就可以随心所欲的进行 coding 了。 46 | 47 | 当功能模块实现完之后,我们可以方便的通过`npm run build`来进行模块打包,打包后的模块压缩包会生成在`assets`文件夹下,然后通过`npm run release`发布(目前`release`命令在`demo`阶段还未开发)。 48 | 49 | 这样一番操作之后一个独立的功能模块包就实现好了,是不是非常的简单😄~ 50 | 51 | 52 | ### 公共依赖抽离 53 | 54 | 上面我们介绍,我们只需要`capricorn init`就可以初始化一个模块项目,那么如果每一个项目都独立打包自己的三方依赖包,那么最终生成的页面体积就会非常的庞大。 55 | 出于这个考虑,我们肯定需要做三方依赖抽离,将这些公共的依赖统一在全局管理,供所有的功能模块使用。 56 | 那么将公共依赖放在基础页面模版里就是一个比较好的选择了。 57 | 58 | ```html 59 | 60 | 61 | 62 | capricorn 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | ``` 78 | 79 | 这是默认模版里的代码,我们可以看到`react.production.min.js`和`react-dom.production.min.js`这两个基础依赖都采用了`cdn`引用方式,不再通过依赖包的方式注入到项目中,这样可以让所有的功能模块共同使用同一个资源包。 80 | 81 | ### 模块通信 82 | 83 | [自定义页面系统设计(二)](https://monajs.github.io/2018/10/15/%E8%87%AA%E5%AE%9A%E4%B9%89%E9%A1%B5%E9%9D%A2%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1%EF%BC%88%E4%B8%80%EF%BC%89/)中介绍过,我们将模块从页面中抽离出来之后,它们都是独立的个体。我们需要提供一个桥梁去支持模块之间的通信。 84 | 85 | ```js 86 | import Events from 'mona-events' 87 | 88 | !window.Capricorn && (window.Capricorn = {}) 89 | 90 | // 摩羯系统全局消息监听机制,负责模块间通信 91 | window.Capricorn.Events = Events 92 | window.Capricorn.events = new Events 93 | ``` 94 | 95 | [mona-events`](https://www.npmjs.com/package/mona-events)是一个事件管理的三方依赖包,这里我们通过[事件监听与消息派发的机制](https://monajs.github.io/2018/08/24/%E7%9B%91%E5%90%AC%E8%80%85%E6%A8%A1%E5%BC%8F%E5%AE%9E%E6%88%98%E5%BA%94%E7%94%A8/)来促成模块间的通信。 96 | 97 | 下面来看一个🌰: 98 | 99 | ```js 100 | // module-A 101 | 102 | ... 103 | window.Capricorn.events.on('module_A_test', (res) => { 104 | console.log('接收到消息') 105 | console.log(res) 106 | // do something 107 | }) 108 | ... 109 | ``` 110 | 111 | ```js 112 | // module-B 113 | 114 | ... 115 | window.Capricorn.events.emit('module_A_test', { 116 | moduleName: 'module-B', 117 | message: 'send message!' 118 | }) 119 | ... 120 | ``` 121 | 122 | 这样`module-A`就能响应`module-B`的交互请求了哈~ 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /source/_posts/监听者模式实战应用.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 监听者模式实战应用 3 | date: 2018-08-24 20:11:41 4 | tags: 5 | --- 6 | 7 | ### 概述 8 | 监听者模式其实就是一种简单的前端思维模式,在前端领域遍地都是。 9 | 当它被应用到合适的场景下你就会感受到它的魅力。 10 | 11 | 下面我们拿商品曝光打点起个头来讲述一下监听者模式可以怎么来应用。 12 | 13 | ### 性能比较差的商品曝光方法 14 | 在互联网电商领域,商品曝光打点可以说再平常不过了,我们需要通过商品的曝光度,来合理的安排商品主推等等。 15 | 那么这东西可以怎么实现呢? 16 | 一些同学可能会立马说,在页面滚动的时候去拿到每一个商品类目,再判断是不是已经处在屏幕内,然后上报接口嘛!!! 17 | 当然这样做肯定能达到商品曝光的目的,但是会不会存在什么隐患或者性能问题呢? 18 | 我们可以看出如果每次滚动都去拿一遍商品类目,每次都需要遍历访问一次 `dom`,然后每次都还需要拿到节点的 `scrollTop `,这样就又触发了浏览器的重排重绘(重排重绘可是性能杀手哈😂)。 19 | 20 | ### 换个角度想问题 21 | 我们现在来分析一下,这样的方式问题出在哪几个点: 22 | 1. 每次滚动的时候你都需要遍历子节点 , `dom`操作的开销可是非常大的,更何况那么的频繁,而且已经曝光的点也会被你遍历取到,数据量一大的话~~~ 23 | 2. 判断节点是否需要曝光的时候都需要实时取一遍位置信息,这样就又触发了重排重绘,而且每次都需要取,好可怕~~ 24 | 25 | 接下来我们就针对这几个点来分析一下: 26 | - 针对第一个点,我们可以变更一下思路,将节点信息格式化初始化的时候找个数组存储起来。然后后续滚动触发的时候就只是简单的遍历这个数组,并且已经成功打点的项就从数组中删除,如此这个数组的长度就是可控的 27 | - 针对第二点,我们可以只在初始化的时候读取一次`scrollTop`,同样插入到被格式化的节点数据中。然后后续都从节点数据中取,这样就大幅减少重排重绘 28 | 29 | 分析到这里,好像已经比较之前的方式优美了不少,性能也优化了很多。但是我们还是需要每次都遍历一个数组去循环判断是否曝光,而且数组如果是动态(像下拉加载分页这样)的话,可能代码就会变的不怎么优美。那么有没有什么办法可以让代码更优美呢?接下来来介绍一下监听者模式的应用~~ 30 | 31 | ### 监听者模式介绍 32 | 听到监听者模式,大家第一反应应该是事件系统,说的简单一点就是消息的订阅和分发。[mona-events](https://www.npmjs.com/package/mona-events)这是一个简单的`JS`事件体系。 33 | 举一个🌰: 34 | 假设有一天你的老大突然想出去吃顿好的,然后在微信群里就吼了一声说:“你们谁要跟我出去一起吃饭吗?” 35 | 员工A:“我要回家吃饭,我不去。” 36 | 员工B:“我去的。” 37 | 员工C:“我要加班,我不去。” 38 | ... 39 | 这就是一个监听者模式的引用了哈😁😁😁 40 | 41 | 接下来我们再来举一个例子对比一下: 42 | 同样还是你的老大突然想出去吃饭,不过这次不是在微信群里了,他是挨个挨个的问了一遍,然后问了30个人终于找到两个人陪他出去吃饭了~~ 43 | 44 | ### 让我们为商品曝光打点提升一下幸福感 45 | 现在我们在每一个商品节点加载结束的时候就对这个商品绑定一个事件。 46 | 然后当页面滚动的时候,只需要在全局📢一个通知,告知商品页面滚动了,商品自己判断自己需不需要进行曝光。 47 | 并且节点有自己的行为,跟容器节点相互独立,因此就不需要考虑分页这些会带来的问题。 48 | 49 | #### 步骤: 50 | - 商品节点自觉的进行滚动事件`命名:scroll-emit-event`监听,并存储节点`scrollTop`值 51 | - 容器滚动的时候分发`scroll-emit-event`消息通知 52 | - 商品节点自行判断是否满足曝光条件 53 | 54 | 55 | ### 感受到简单的幸福之后,当然要更幸福啦 56 | 接下来我们通过几个点来更好的优化一下: 57 | - 页面滚动当然要进行节流啦,你可以设置一个`200ms` 的`setTimeout`哟 58 | - 商品上报曝光接口成功之后就要取消掉自个儿的监听哈 59 | 60 | 介绍完这些之后大家可以联想一下,图片懒加载、页面按需加载这些都可以按照这个套路来实现 61 | 62 | #### 这里准备了两个demo 63 | 64 | - [Mona系列 - React滚动监听组件](https://www.npmjs.com/package/mor-scroll-watcher) 65 | > 这是我抽象出来的一个滚动监听组件 66 | 67 | - [Mona系列-React图片懒加载](https://www.npmjs.com/package/mor-lazyload-img) 68 | > 这是基于 [Mona系列 - React滚动监听组件](https://www.npmjs.com/package/mor-scroll-watcher) 实现的一个图片懒加载组件 69 | 70 | ### 将监听者模式跟业务相结合 71 | 经过上面的介绍之后,对事件应用有了一定的了解,那么如何更具艺术性的在业务中使用,让我们的代码更加清晰可维护呢? 72 | 73 | ![1](http://static.monajs.cn/example/events.gif) 74 | 75 | 这是一个在日常开发中非常常见的场景,通过弹层来进行一些操作,然后同步更新页面数据 76 | 77 | 我们通常会通过将更新页面数据的一个执行回调传递到弹层模块中去,然后在弹层操作成功之后执行 78 | 79 | 这样做自然没有什么问题,但是随着业务的复杂度提升,我们可能需要传递的执行回调就会越来越多,层级可能就不再是简单的父子级关系 80 | 我们可以预见我们即将碰到跨很多级传递回调函数的场景,代码即将变的难以维护 81 | 82 | 接下来我们来讨论一个比较巧妙的方式: 83 | ```js 84 | // baseServer.js 85 | import Events from 'mona-events'; 86 | export default class BaseServer extends Events {} 87 | ``` 88 | 89 | ```js 90 | // server.js 91 | import BaseServer from 'core/baseServer' 92 | 93 | class TestServer extends BaseServer { 94 | test () { 95 | return new Promise((resolve, reject) => { 96 | // 模拟后端接口请求 97 | setTimeout(() => { 98 | resolve('你的模样') 99 | }, 1000) 100 | }).then(res => { 101 | this.emit('changeText', res) 102 | return res 103 | }) 104 | } 105 | } 106 | 107 | export default new TestServer 108 | ``` 109 | ```js 110 | // page.jsx 111 | ... 112 | componentWillMount () { 113 | TestServer.on('changeText', res => { 114 | this.text = res 115 | this.setState({}) 116 | }) 117 | } 118 | ... 119 | ``` 120 | ```js 121 | // modal.jsx 122 | ... 123 | handleOk () { 124 | this.loading = true 125 | this.setState({}) 126 | TestServer.test().then(() => { 127 | this.loading = false 128 | Notification.info({ 129 | message: '文案修改成功!' 130 | }) 131 | this.visible = false 132 | this.setState({}) 133 | }) 134 | 135 | } 136 | ... 137 | ``` 138 | 139 | 通过代码我们可以看到,我们将监听者模式跟后端请求接口巧妙的结合在了一起 140 | 当弹层上的操作请求成功返回之后我们分发一个`changeText`事件,页面收到这个消息之后就触发了更改页面信息的操作 141 | 142 | ✨✨这样就巧妙的避免了多级传递执行回调的问题,而且可以在任何地方触发`changeText`事件,规避掉了很多冗余的重复逻辑,代码自然就变的简单了 143 | 144 | 注意一点:这里介绍了这种方法不代表所有这种场景都用这种方式,简单的父子级关系当然是直接传递参数比较简单易读 145 | 146 | > 之所以优美,是因为应用在了它最合适的场景 147 | 148 | 监听者模式还可以应用在各种复杂的场景,大家可以自己慢慢探索 149 | 这篇文章主要是为了提供一个前端思维模式,代码仅供参考 150 | -------------------------------------------------------------------------------- /source/_posts/理解一发“请求跨域”.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 理解一发“请求跨域” 3 | date: 2018-07-18 20:08:57 4 | tags: 5 | --- 6 | 7 | ### 概述 8 | 在前端开发者眼里,“跨域”就像你女朋友一样,让你又爱又恨,而且你还拿它一点办法都没有。 9 | 平时开发中,你发现这东西特别安静,安静到你大半年碰不到一次,但是到面试的时候,这家伙就时不时的出来难一难你。 10 | 今天我们出于仁道主义,还是一起来研究研究一下“跨域”这个东西! 11 | 12 | ### 为什么会出现跨域这个问题 13 | 我们这种搬砖的,碰到“跨域”的时候,心里可能会想是哪个人设计的“跨域”限制?这东西那么鸡肋,只会加重我的开发成本,为什么还要设计这个玩意呢? 14 | 这么追溯下去,其实“跨域”是一种浏览器行为,是[浏览器的同源策略](https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy)导致了跨域。 15 | 浏览器给出的官网解释是“同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。” 16 | 这么听下来,我们好像可以理解为浏览器为了保护访问者的信息安全而牺牲了一些东西。 17 | 18 | ### 如果没有浏览器的同源策略又会怎么样呢? 19 | 接下来我们就要搞明白,浏览器的安全策略到底是保护哪种用户行为? 20 | 实际上,浏览器是对两种行为添加了同源限制。 21 | - 接口请求 22 | - `dom`查询 23 | 24 | ### 接下来我们来看看没有同源限制会怎样的结果 25 | - 接口请求 26 | 我们拿用户登陆(`www.func-star.com/#/login`)来举个🌰,我们都知道用户登陆成功之后会将用户信息种到 `cookie` (或者其他)中。后续再发送请求的时候,就会自动在请求头携带 `cookie` 信息用来标识用户。 27 | 在你登陆成功之后你开始访问 `www.func-star.com` 站点下的其他页面,突然你的一个同事给你发了一个链接 `www.wohuiluanlai.com` 这个网站内部逻辑就负责向 `www.func-star.com` 中干各种坏事。 28 | 因为没有同源限制,所以 `www.wohuiluanlai.com` 和 `www.func-star.com` 的用户信息就是通的,干的所有坏事都是以登陆者身份干的,合理合法。 29 | 说到这,我们就会想 `cookie` 这东西我复制一下粘过去不是一样很简单,同源限制好像并不是很有必要。那么我们就要想是不是有办法限制 `cookie` 的操作呢?实际上,服务端可以设置 `httpOnly`,使得前端无法操作cookie。 30 | - dom查询 31 | 现在假设有两个网站 `A: www.zhifubao.com | B:www.zhifuba.com` ,这两域名就差了一个字符,也就是我们常说的钓鱼网站。 32 | 33 | ```js 34 | // www.zhifuba.com 35 | // HTML 36 | 37 | // JS 38 | // 由于没有同源策略的限制,钓鱼网站可以直接拿到别的网站的Dom 39 | const iframe = window.frames['zhifubao'] 40 | const username = iframe.document.getElementById('username') 41 | const password = iframe.document.getElementById('password') 42 | ``` 43 | 现在假设你没有注意点进去了 `www.zhifuba.com`,如果没有浏览器的同源策略,钓鱼网站就非常轻而易举的拿到你的用户名和密码。 44 | 45 | #### 另外,网络没有绝对的安全,哪怕同源策略的存在,也会有办法绕过这道限制。很多场景下考虑的是有没有必要,以及绕过这道限制所花费的成本能不能获取到对应的结果。 46 | 47 | ### 既然同源策略不可避免,那么我们又有什么解决办法呢? 48 | 49 | 为了让请求更加安全,浏览器有同源策略来限制跨域请求,那总不能不让开发者来进行跨域请求呀! 50 | 下面我们来介绍一下几种常用的跨域请求方式。 51 | 52 | #### 1.`jsonp` 53 | 前面我们讨论了那么久像 dom 查询和接口请求都被浏览器的同源策略限制了,但是像 `scripts` 这样的脚本资源,浏览器是没有进行限制的。 54 | 我们可以讨巧的用服务端自执行回调函数的形式,通过前后端约定函数名来达成数据交互的目的。 55 | ```js 56 | // jsonp 57 | class Ajax { 58 | param(data){ 59 | let _t = []; 60 | Object.keys(data).forEach(function(vi){ 61 | if(data[vi] !== undefined){ 62 | _t.push(vi+"="+data[vi]); 63 | } 64 | }); 65 | return _t.join("&"); 66 | } 67 | jsonp(url, data, cbkName, time_out = 10) { 68 | return new Promise((resolve, reject) => { 69 | if (!cbkName) { 70 | cbkName = 'jsonp' + (Date.now()) 71 | } 72 | data = data ? data : {}; 73 | Object.assign(data, { 74 | callback: cbkName 75 | }) 76 | let script = document.createElement("script"); 77 | script.async = 'async'; 78 | script.src = url + '?' + this.param(data); 79 | window[cbkName] = function(res) { 80 | resolve(res) 81 | delete(window[cbkName]) 82 | } 83 | let timeout = setTimeout(() => { 84 | window[cbkName] = function() {}; 85 | reject("请求超时") 86 | }, time_out * 1000) 87 | script.onload = function() { 88 | clearTimeout(timeout); 89 | setTimeout(() => { 90 | script.remove() 91 | }, 500) 92 | } 93 | script.onerror = function() { 94 | reject("请求失败") 95 | setTimeout(() => { 96 | script.remove() 97 | }, 500) 98 | } 99 | document.body.appendChild(script) 100 | }) 101 | } 102 | } 103 | export default new ajax; 104 | ``` 105 | 106 | #### 2.`ifram`的应用 107 | 不难发现,上面的🌰支持了 `get` 形式的跨域请求,因为资源加载也是 `get` 形式的。 108 | 那么如果我们要支持 `post` 形式的请求又需要怎么做呢? 109 | 回想一下以前前后端不分离的年代,`ajax `还没有流行起来的时候,`
` 标签大家一定印象还很深,它可以设置 `method` 属性,并且支持 `post` 。 110 | 接下来我们就来创建一个虚拟的 `form` 和一个 虚拟的 `ifram` 来模拟一番。 111 | 112 | ```js 113 | class Ajax { 114 | jsonpPost(url, data) { 115 | new Promise((resolve, reject) => { 116 | const iframe = document.createElement('iframe') 117 | iframe.name = 'iframePost' 118 | iframe.style.display = 'none' 119 | document.body.appendChild(iframe) 120 | const form = document.createElement('form') 121 | const node = document.createElement('input') 122 | iframe.onload = function(data) { 123 | console.log('请求成功') 124 | resolve(data || { success: true }) 125 | } 126 | script.onerror = function(data) { 127 | console.log('请求失败') 128 | reject(data || { success: false }) 129 | } 130 | form.action = url 131 | // 在指定的iframe中执行form 132 | form.target = iframe.name 133 | form.method = 'post' 134 | for (let name in data) { 135 | node.name = name 136 | node.value = data[name].toString() 137 | form.appendChild(node.cloneNode()) 138 | } 139 | form.style.display = 'none' 140 | document.body.appendChild(form) 141 | form.submit() 142 | document.body.removeChild(form) 143 | }) 144 | 145 | } 146 | } 147 | export default new ajax; 148 | ``` 149 | 150 | #### 3.`CORS` 151 | `CORS`是一个`W3C`标准,全称是”跨域资源共享”(Cross-origin resource sharing)。看起来这是个比较官方的解决方案,都进`W3C`标准了。 152 | 对于前端开发者来讲,这是一个非常棒的东西,因为不需要绕来绕去只为了发一个请求。 153 | 我们还是按照原来不跨域的方式去发送请求,只需要后端的接口支持一下跨域,问题就解决了,貌似是把问题抛给了后端。。。 154 | 详细说明可以阅读 [CORS——跨域请求那些事儿](https://blog.csdn.net/u014344668/article/details/54948546) 155 | 156 | #### 4.`nginx`代理 157 | 一起研究了那么多方法,都是在讨论怎么解决跨域。那有没有办法把跨域的请求直接转发到正确的后端服务器上呢?这样不是更省事吗。 158 | 大家肯定都想到了 `nginx` 这个神器了。下面来看一下具体怎么配置: 159 | 160 | ```js 161 | // nginx 配置 162 | server{ 163 | listen 8888; 164 | server_name otherserver; 165 | location ^~ /api { 166 | proxy_pass http://currentserver:8080; 167 | } 168 | } 169 | ``` 170 | 添加这个配置之后,前端同学就不需要再考虑跨域的问题了。所有匹配 `otherserver:8888/api` 格式的接口都会被代理转发到 `http://currentserver:8080` 服务器上。 171 | 这样前端在前后端数据交互的时候就不需要考虑跨域的问题。 172 | 173 | 174 | 175 | 参考文章: 176 | [不要再问我跨域的问题了](http://web.jobbole.com/94928/) 177 | [CORS——跨域请求那些事儿](https://blog.csdn.net/u014344668/article/details/54948546) -------------------------------------------------------------------------------- /source/_posts/Promise介绍.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Promise介绍 3 | date: 2018-06-26 20:01:10 4 | tags: 5 | --- 6 | 7 | ![1](https://user-images.githubusercontent.com/13312192/38787780-b97c1180-4162-11e8-81a2-346b6ce0b1b3.png) 8 | 9 | 可以看到`Promise`其实是个构造函数,原型上挂着`catch`和`then`方法,自身拥有`race`、`all`、`reject`、`resolve`等方法。 10 | 11 | 那既然是构造函数,那我们就直接`new`一个来看一下。 12 | 13 | ```js 14 | var promise = new Promise(function (resolve, reject) { 15 | setTimeout(function () { 16 | console.log('第一个异步请求开始') 17 | resolve('请求返回'); 18 | }) 19 | }) 20 | // 第一个异步请求开始 21 | ``` 22 | 我们可以看到,`Promise()`接收一个包含两个参数的函数,两个参数分别为`resolve`和`reject`,对应着成功和失败。而且在实例化一个`Promise`的时候,回调函数会马上执行。 23 | 24 | ```js 25 | function promise() { 26 | return new Promise(function (resolve, reject) { 27 | setTimeout(function () { 28 | console.log('第一个异步请求开始'); 29 | resolve('成功返回'); 30 | }) 31 | }) 32 | } 33 | ``` 34 | 通过这个函数,我们来看下面的`demo`: 35 | 36 | ```js 37 | promise().then(function(data){ 38 | console.log(data) 39 | }) 40 | // 第一个异步请求开始 41 | // 成功返回 42 | ``` 43 | 44 | `第一个异步请求开始`被打印出来肯定都清楚,可是`成功返回`也被打印出来了。前面介绍到 `Promise` 构造函数的原型上挂着两个 `catch` 和 `then` 两个方法,我们可以在 `Promise` 实例上链式调用`.then()`。 45 | 46 | `.then()` 可以接收两个回调函数作为参数,第一个对应 `fullfiled(resoleved、成功)` 执行,第二个对应 `rejected(失败)` 执行。并且这两个回调函数能拿到前面 `resolve(arg)` 和 `reject(arg)` 传入的参数。 47 | 48 | 接下来`reject`同理: 49 | 50 | ```js 51 | function promise() { 52 | return new Promise(function(resolve, reject) { 53 | setTimeout(function() { 54 | console.log('第一个异步请求开始'); 55 | reject('失败返回'); 56 | }) 57 | }) 58 | } 59 | promise().then(function(data) { 60 | console.log(data) 61 | }, function(data) { 62 | console.log(data) 63 | }) 64 | // 第一个异步请求开始 65 | // 失败返回 66 | ``` 67 | 68 | 我们接着来看下面的`demo`: 69 | 70 | ```js 71 | function promise() { 72 | return new Promise(function(resolve, reject) { 73 | setTimeout(function() { 74 | console.log('第一个异步请求开始'); 75 | resolve('成功返回'); 76 | reject('失败返回'); 77 | }, 1000) 78 | }) 79 | } 80 | promise().then(function(data) { 81 | console.log(data) 82 | }, function(data) { 83 | console.log(data) 84 | }) 85 | // 第一个异步请求开始 86 | // 成功返回 87 | ``` 88 | 89 | 我们可以看到这里的 `reject('失败返回')` 根本没有被触发。实际上,`promise` 的状态只会从 `pending` 到 `resolved` 或者 `pending` 到 `rejected`。 90 | 91 | 简单的说就是一个处理成功的过程和一个处理失败的过程,而且一旦得到结果,状态就不能改变。 92 | 93 | 接下来我们来看一下 `Promise`的链式调用,如何将异步代码以同步模式组织起来: 94 | 95 | ```js 96 | function test1() { 97 | return new Promise(function(resolve, reject) { 98 | setTimeout(function() { 99 | console.log('异步操作1开始'); 100 | resolve('成功返回test1'); 101 | }, 1000) 102 | }); 103 | } 104 | 105 | function test2() { 106 | return new Promise(function(resolve, reject) { 107 | setTimeout(function() { 108 | console.log('异步操作2开始'); 109 | resolve('成功返回test2'); 110 | }, 1500) 111 | }); 112 | } 113 | 114 | test1().then(function(data) { 115 | console.log(data) 116 | return '非Promise' //看这里 117 | }).then(function(data) { 118 | console.log(data); 119 | return test2(); 120 | }).then(function(data) { 121 | console.log(data); 122 | }) 123 | // 异步操作1开始 124 | // 成功返回test1 125 | // 非Promise 126 | // 异步操作2开始 127 | // 成功返回test2 128 | ``` 129 | 130 | 这里我们可以发现 `.then()` 中如果不返回一个 `Promise` 实例而是返回一个值,也能被下一个 `.then()` 方法接收到。 131 | 132 | ### `.then()`的原理(可以前往[Promise原理篇](https://github.com/func-star/promise/wiki/Promise%E5%8E%9F%E7%90%86%E7%AF%87)查看) 133 | 134 | ```js 135 | this.then = function(onFulfilled) { 136 | return new Promise(function(resolve) { 137 | function handle() { 138 | 139 | var returnVal = isFn(onFulfilled) && onFulfilled(promise.value) || promise.value; 140 | // var returnVal = onFulfilled(promise.value); 141 | if (isFn(returnVal.then)) { 142 | returnVal.then(function(res) { 143 | resolve(res) 144 | }) 145 | } else { 146 | resolve(returnVal); 147 | } 148 | } 149 | if ('PENDING' === promise.status) { 150 | promise._resolveList.push(handle); 151 | } else if ('FULFILLED' === promise.status) { 152 | handle(promise.value) 153 | } 154 | }) 155 | } 156 | ``` 157 | 除了 `then`, 在 `Promise` 的构造函数的原型中还有一个 `catch()` 方法,这个方法其实很容易理解,`catch` 会将 `Promise` 的执行报错和 `resolve` 执行过程中的报错呈现出来,而 `reject` 无法获取 `resolve` 执行过程中的报错。 158 | 159 | 接下来让我们来看下`.all()`的用法 160 | 161 | ```js 162 | function test1() { 163 | return new Promise(function(resolve, reject) { 164 | setTimeout(function() { 165 | console.log('异步操作1开始'); 166 | resolve('成功返回1'); 167 | }, 1000) 168 | }); 169 | } 170 | 171 | function test2() { 172 | return new Promise(function(resolve, reject) { 173 | setTimeout(function() { 174 | console.log('异步操作2开始'); 175 | resolve('成功返回2'); 176 | }, 1500) 177 | }); 178 | } 179 | 180 | function test3() { 181 | return new Promise(function(resolve, reject) { 182 | setTimeout(function() { 183 | console.log('异步操作3开始'); 184 | resolve('成功返回3'); 185 | }, 1000) 186 | }); 187 | } 188 | Promise.all([ 189 | test1(), 190 | test2(), 191 | test3() 192 | ]).then(function(results) { 193 | console.log(results); 194 | }).catch(function(reason) { 195 | console.log(reason); 196 | }) 197 | // 异步操作1开始 198 | // 异步操作2开始 199 | // 异步操作3开始 200 | // Array ["成功返回1", "成功返回2", "成功返回3"] 201 | ``` 202 | 203 | `.all()` 的作用相当于把三个异步操作并成一个来执行,等所有的异步操作都返回后,统一进入到 `.then()`。 204 | 205 | 那么大家普遍都会有疑问,如果其中一个异步操作`reject`了呢,结果会怎样,现在我把第二个修改下 206 | 207 | ```js 208 | function test2() { 209 | return new Promise(function(resolve, reject) { 210 | setTimeout(function() { 211 | console.log('异步操作2开始'); 212 | reject('拒绝返回2') 213 | }, 1500) 214 | }); 215 | } 216 | // 异步操作1开始 217 | // 异步操作2开始 218 | // 异步操作3开始 219 | // 拒绝返回2 220 | ``` 221 | 222 | 结果是 `.then()` 中的回调函数只接收了 `rejected` 状态的值而且不再是一个数组。 223 | 224 | 接下来来看一下 `.race()` 方法,这个方法的用法和 `.all()` 差不多,区别在于它不是当所有异步操作都结束后才进入 `.then()`,而 `.race` 是任意其中一个结束它就进入 `.then()` 方法。 225 | ```js 226 | function test1() { 227 | return new Promise(function(resolve, reject) { 228 | setTimeout(function() { 229 | console.log('异步操作1开始'); 230 | resolve('成功返回1'); 231 | }, 1000) 232 | }); 233 | } 234 | 235 | function test2() { 236 | return new Promise(function(resolve, reject) { 237 | setTimeout(function() { 238 | console.log('异步操作2开始'); 239 | resolve('成功返回2'); 240 | }, 1500) 241 | }); 242 | } 243 | Promise.race([ 244 | test1(), 245 | test2() 246 | ]).then(function(results) { 247 | console.log(results); 248 | }).catch(function(reason) { 249 | console.log(reason); 250 | }) 251 | // 异步操作1开始 252 | // 成功返回1 253 | // 异步操作2开始 254 | ``` 255 | -------------------------------------------------------------------------------- /source/_posts/React简析之节点挂载.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: React简析之节点挂载 3 | date: 2018-07-16 20:08:17 4 | tags: 5 | --- 6 | 7 | #### 概述 8 | 在 [React简析之实例化(一)](https://github.com/func-star/blog/issues/10) 中,我们将节点进行了实例化,得到了一个数据装载完整的 `React` 实例数据。这一节我们来介绍一下节点挂载的过程。 9 | 代码地址:[v1.1](https://github.com/func-star/blog/issues/10) 10 | 11 | ```js 12 | // 挂载节点 13 | mount(parentNode) { 14 | if (this.nodeType === Constant.EMPTY_NODE) { 15 | return null 16 | } 17 | 18 | if (this.nodeType === Constant.REACT_NODE) { 19 | let componentObj = new this.currentElement.type(this.currentElement.props) 20 | // component实例 21 | this.componentObj = componentObj 22 | // 获取react render()出来的真实节点信息 23 | let componentElement = componentObj.render() 24 | if (!componentElement) { 25 | return null 26 | } 27 | this.componentElement = componentElement 28 | // 监听setState方法 29 | this.componentObj.__events.on('stateChange', () => { 30 | this.receiveComponent() 31 | }) 32 | this.componentInstance = new ReactInstantiate(this.componentElement, null) 33 | let node = this.componentInstance.mount(parentNode) 34 | return node 35 | } 36 | 37 | if (!this.nativeNode) { 38 | this.nativeNode = reactDom.create(this.currentElement) 39 | // 事件绑定 40 | if (this.nodeType === Constant.NATIVE_NODE && this.currentElement.props) { 41 | reactEvents.register(this.nativeNode, this.currentElement.props) 42 | } 43 | if (parentNode) { 44 | this.parentNode = parentNode 45 | parentNode.appendChild(this.nativeNode) 46 | } 47 | } 48 | 49 | this.nativeNode['__reactInstance'] = { 50 | _currentElement: this.currentElement 51 | } 52 | 53 | this.mountChildren(this.nativeNode) 54 | return this.nativeNode 55 | } 56 | 57 | // 挂载子节点// 挂载节点 58 | mount(parentNode) { 59 | if (this.nodeType === Constant.EMPTY_NODE) { 60 | return null 61 | } 62 | 63 | if (this.nodeType === Constant.REACT_NODE) { 64 | let componentObj = new this.currentElement.type(this.currentElement.props) 65 | // component实例 66 | this.componentObj = componentObj 67 | // 获取react render()出来的真实节点信息 68 | let componentElement = componentObj.render() 69 | if (!componentElement) { 70 | return null 71 | } 72 | this.componentElement = componentElement 73 | // 监听setState方法 74 | this.componentObj.__events.on('stateChange', () => { 75 | this.receiveComponent() 76 | }) 77 | this.componentInstance = new ReactInstantiate(this.componentElement, null) 78 | let node = this.componentInstance.mount(parentNode) 79 | return node 80 | } 81 | 82 | if (!this.nativeNode) { 83 | this.nativeNode = reactDom.create(this.currentElement) 84 | // 事件绑定 85 | if (this.nodeType === Constant.NATIVE_NODE && this.currentElement.props) { 86 | reactEvents.register(this.nativeNode, this.currentElement.props) 87 | } 88 | if (parentNode) { 89 | this.parentNode = parentNode 90 | parentNode.appendChild(this.nativeNode) 91 | } 92 | } 93 | 94 | this.nativeNode['__reactInstance'] = { 95 | _currentElement: this.currentElement 96 | } 97 | 98 | this.mountChildren(this.nativeNode) 99 | return this.nativeNode 100 | } 101 | 102 | // 挂载子节点 103 | mountChildren(parentNode) { 104 | if (!this.childrenInstance || this.childrenInstance.length === 0) { 105 | return 106 | } 107 | this.childrenInstance.forEach((v) => { 108 | if (Util.isArray(v)) { 109 | v.forEach((child) => { 110 | child.mount(parentNode) 111 | }) 112 | } else { 113 | console.log(parentNode) 114 | v.mount(parentNode) 115 | } 116 | }) 117 | } 118 | ``` 119 | 120 | #### 这里注意一个点: 121 | 实际上在实例化过程中,我们并不会将 `React` 节点转化成原生节点进行实例化。`React` 节点转化成原生节点这一步是在节点挂载的时候完成的。 122 | 在 `React` 节点挂载的过程中,我们会根据实例化好的节点信息`reactDom.create(this.currentElement)` 创建出一个真实的 原生节点(浏览器节点),然后插入 `dom` 结构中去。 123 | 如果碰到 `React` 节点,则是先通过 `render()` 方法返回的 `dom` 模版,实例化出一份 节点实例,再进行节点挂载。 124 | 依次递归完成子节点的挂载操作。 125 | 126 | #### 合成事件绑定、属性绑定(可以先忽略) 127 | 在 `React` 的节点属性中,通常以驼峰形式命名,像`style`属性接收的也是 `JSON` 对象形式,与原生节点的属性格式不同。 128 | 129 | ```js 130 | prefixList = [ 131 | 'transform', 132 | 'transition' 133 | ]; 134 | cssNumber = [ 135 | "column-count", 136 | "fill-opacity", 137 | "font-weight", 138 | "line-height", 139 | "opacity", 140 | "order", 141 | "orphans", 142 | "widows", 143 | "z-index", 144 | "zoom" 145 | ]; 146 | 147 | //将样式对象转化为可使用的样式对象 148 | parseStyleObj(data) { 149 | let _data = {}; 150 | Object.keys(data).forEach((v) => { 151 | Util.upperToLine(v) 152 | let name = Util.upperToLine(v); 153 | let val = data[v]; 154 | if (typeof(val) == 'number' && this.cssNumber.indexOf(name) < 0) { 155 | val = val + 'px'; 156 | } 157 | _data[name] = val; 158 | if (this.prefixList.indexOf(name) >= 0) { 159 | _data["-webkit-" + name] = val; 160 | } 161 | }) 162 | return _data; 163 | } 164 | styleObjStringify(styleObj) { 165 | if (!styleObj || Object.keys(styleObj).length == 0) { 166 | return ''; 167 | } 168 | return Object.keys(styleObj).map((v) => { 169 | return v + ":" + styleObj[v]; 170 | }).join(";") 171 | } 172 | 173 | //dom信息绑定 174 | parse(node, props) { 175 | if (!props) { 176 | return; 177 | } 178 | let propKeys = Object.keys(props); 179 | 180 | //className 181 | if (Util.has(props, 'className')) { 182 | if (props.className) { 183 | node.className = props.className; 184 | } 185 | Util.arrayDelete(propKeys, "className") 186 | } 187 | 188 | //style 189 | if (Util.has(props, 'style')) { 190 | let style = this.parseStyleObj(props.style); 191 | node.setAttribute("style", this.styleObjStringify(style)); 192 | Util.arrayDelete(propKeys, "style") 193 | } 194 | 195 | //defaultValue 196 | if (Util.has(props, 'defaultValue')) { 197 | node.setAttribute("value", props.defaultValue); 198 | Util.arrayDelete(propKeys, "defaultValue") 199 | } 200 | 201 | //dangerouslySetInnerHTML 202 | if (Util.has(props, 'dangerouslySetInnerHTML')) { 203 | if (!props.dangerouslySetInnerHTML || !props.dangerouslySetInnerHTML.__html) { 204 | return; 205 | } 206 | node.innerHTML = props.dangerouslySetInnerHTML.__html; 207 | Util.arrayDelete(propKeys, "dangerouslySetInnerHTML") 208 | } 209 | 210 | propKeys.forEach((v) => { 211 | let val = props[v]; 212 | if (Util.isUndefined(val)) { 213 | return; 214 | //val = true; 215 | } 216 | 217 | if (DOMPropertyConfig.isProperty(v)) { 218 | let attr = Util.upperToLine(v) 219 | if (v == 'htmlFor') { 220 | attr = 'for'; 221 | } 222 | if (val === false) { 223 | node.removeAttribute(attr); 224 | return; 225 | } 226 | if (val === true) { 227 | node.setAttribute(attr, 'true'); 228 | } else { 229 | node.setAttribute(attr, val); 230 | } 231 | return; 232 | } 233 | 234 | //data-* 235 | if (/^data-.+/.test(v) || /^aria-.+/.test(v)) { 236 | node.setAttribute(v, val); 237 | return; 238 | } 239 | 240 | //事件绑定 241 | let e = DOMPropertyConfig.getEventName(v); 242 | if (e) { 243 | if (Util.isFun(val)) { 244 | node.addEventListener(e, (ev) => { 245 | val(); 246 | }, false) 247 | } 248 | } 249 | }) 250 | } 251 | ``` 252 | #### `setState` 介绍 253 | 在理解 `React` 之前我们都会把 `setState` 当成是一个异步过程,下面见一个例子: 254 | ```js 255 | class App extends Component { 256 | state = { val: 0 } 257 | increment = () => { 258 | this.setState({ val: this.state.val + 1 }) 259 | console.log(this.state.val) // 输出的是更新前的val --> 0 260 | } 261 | render () { 262 | return ( 263 |
test
264 | ) 265 | } 266 | } 267 | 268 | ``` 269 | 从结果上看,我们很容易把 `setState` 当成是一个异步方法。 270 | 其实 `setState` 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的,只是 `increment`(钩子函数)的调用顺序在更新之前,导致在钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 `setState(partialState, callback)` 中的`callback`拿到更新后的结果。 271 | 那么如何让 `setState` 以同步形式使用呢? 272 | 273 | - 用 `setTimeout` 的形式强制改变调用栈 274 | - 用原生事件绑定形式,不使用 `React` 的合成事件 275 | 276 | ```js 277 | componentDidMount() { 278 | document.body.addEventListener('click', this.changeValue, false) 279 | } 280 | ``` 281 | 282 | 建议跑一下代码试试:[v1.1](https://github.com/func-star/blog/issues/10) 283 | -------------------------------------------------------------------------------- /source/_posts/Promise原理.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Promise原理 3 | date: 2018-06-26 20:04:05 4 | tags: 5 | --- 6 | 7 | 在看这篇文章之前建议先看[Promise介绍篇](https://github.com/func-star/promise/wiki/Promise%E4%BB%8B%E7%BB%8D%E7%AF%87)和[Promise实战篇](https://github.com/func-star/promise/wiki/Promise%E5%AE%9E%E6%88%98%E7%AF%87),对 `promise` 有一定的了解能更高效的理解其原理。 8 | 9 | 我们通过`demo`来看一下 `Promise` 的一些特性。 10 | ```js 11 | new Promise(function(resolve) { 12 | resolve('B') 13 | }).then(function(res) { 14 | console.log(res) 15 | }) 16 | 17 | console.log('A') 18 | // A、B 19 | ``` 20 | 通过前面两篇文章的介绍,我们了解到: 21 | 1. `Promise`的参数会立即执行,不受执行状态的影响。 22 | 2. `then` 负责添加后续要执行的回调函数。 23 | 3. 从程序实现上可以理解为把`then`方法的函数参数添加到一个执行队列,然后在`Promise`的状态从 `pending` 改变为 `fulfilled` 或者 `rejected`时,遍历执行这个操作队列。 24 | 25 | 接下来我们来实现一下: 26 | 27 | ### 雏形实现 28 | ```js 29 | function Promise(fn) { 30 | var promise = this; 31 | promise.callBackList = []; 32 | 33 | this.then = function(fn) { 34 | this.callBackList.push(fn) 35 | } 36 | 37 | function resolve(value) { 38 | promise.callBackList.forEach(function(cb) { 39 | cb(value) 40 | }) 41 | } 42 | fn(resolve) 43 | } 44 | ``` 45 | 接下来我们用我们刚实现的 `Promise` 来验证一把: 46 | ```js 47 | new Promise(function(resolve) { 48 | resolve('B') 49 | }).then(function(res) { 50 | console.log(res) 51 | }) 52 | 53 | console.log('A') 54 | // A 55 | ``` 56 | 我们发现这个结果与我们预期的输出结果不一样,我们预期会先输出一个`A`然后输出`B`,然而结果却只输出一个`A`。分析一下上面的 `Promise` 雏形实现,不难发现 `resolve` 会先于 `then` 执行,也就是说 `callBackList` 是一个空数组。 57 | 58 | ### 支持异步 59 | 60 | 为了解决这个问题,我们可以为 `resolve` 的执行逻辑添加`setTImeout`,让这段逻辑在`Js`任务队列的末尾执行。 61 | 62 | ```js 63 | function resolve(value) { 64 | setTimeout(function() { 65 | promise.callBackList.forEach(function(cb) { 66 | cb(value) 67 | }) 68 | }) 69 | } 70 | ``` 71 | 72 | ### 支持链式调用 73 | 74 | 经常用 `Promise` 的同学都知道支持链式调用是 `Promise` 的一个优势,它支持将异步的代码以同步的方式来书写,从而使得代码逻辑清晰已读。实际上我们就是让 `.then()` 函数执行后返回`this`。 75 | 76 | ```js 77 | this.then = function(fn) { 78 | this.callBackList.push(fn) 79 | return this 80 | } 81 | ``` 82 | 83 | ### 添加执行状态 84 | 85 | 在[Promise介绍篇](https://github.com/func-star/promise/wiki/Promise%E4%BB%8B%E7%BB%8D%E7%AF%87)中我们介绍过 `Promise` 有 `pending`、`fulfilled`、`rejected` 三个互斥状态,存在 `pending` 到 `fulfilled` 和 `pending` 到 `rejected` 两种场景,而且都是不可逆的。 86 | 87 | 下面结合状态来升级一把我们前面的雏形 `Promise`,这里先介绍`resolve` 执行时的状态变化,后续补充`reject`: 88 | 89 | ```js 90 | function Promise(fn) { 91 | var promise = this; 92 | promise._resolveList = []; 93 | promise.status = 'PENDING'; 94 | promise.value = null; 95 | this.then = function(onFulfilled) { 96 | if ('PENDING' === this.status) { 97 | this._resolveList.push(onFulfilled); 98 | return this; 99 | } 100 | onFulfilled(this.value); 101 | return this; 102 | } 103 | 104 | function resolve(value) { 105 | setTimeout(function() { 106 | promise.status = 'FULFILLED'; 107 | promise.value = value; 108 | promise._resolveList.forEach(function(cb) { 109 | cb(promise.value); 110 | }); 111 | }); 112 | } 113 | fn(resolve) 114 | } 115 | 116 | ``` 117 | 下面来通过个`demo`来验证一发: 118 | ```js 119 | new Promise(function(resolve) { 120 | resolve('B'); 121 | }).then(function(res) { 122 | console.log(res); 123 | }) 124 | 125 | console.log('A'); 126 | // A 、 B 127 | ``` 128 | 129 | 写到这里,简单场景下的 `Promise` 已经实现完毕了。但是在实际应用场景中,`Promise` 大多是串行使用的,会通过很多的 `then`链式调用来拆分一个层级比较深的逻辑。 130 | 131 | ### 串行实现 132 | 133 | 先举个简单的例子来说明: 134 | ```js 135 | new Promise(function(resolve) { 136 | resolve('B'); 137 | }).then(function(res) { 138 | console.log(res); 139 | return 'C' 140 | }).then(function(res) { 141 | console.log(res); 142 | }) 143 | 144 | console.log('A'); 145 | // A 、 B 、 B 146 | ``` 147 | 148 | 通过这个例子,我们发现这输出结果又和我们预期的结果有出入了。我们期望输出 `ABC`,可实际上却输出了 `ABB`。这主要是因为我们的整个 `then` 执行队列中的回调函数都共用了 `resolve` 传进来的同一个 `value`。 149 | 在[Promise介绍篇](https://github.com/func-star/promise/wiki/Promise%E4%BB%8B%E7%BB%8D%E7%AF%87)中我们介绍过在`then`中重新返回一个新的 `Promise` 示例,提供给下一个 `then` 的回调函数来使用。 150 | 151 | 来看一下代码实现: 152 | ```js 153 | function Promise(fn) { 154 | var promise = this; 155 | promise._resolveList = []; 156 | promise.status = 'PENDING'; 157 | promise.value = null; 158 | 159 | this.then = function(onFulfilled) { 160 | return new Promise(function(resolve) { 161 | function handle() { 162 | var value = onFulfilled(promise.value); 163 | resolve(value); 164 | } 165 | if ('PENDING' === promise.status) { 166 | promise._resolveList.push(handle); 167 | } else if ('FULFILLED' === promise.status) { 168 | handle(promise.value) 169 | } 170 | }) 171 | } 172 | 173 | function resolve(value) { 174 | setTimeout(function() { 175 | promise.status = 'FULFILLED'; 176 | promise.value = value; 177 | promise._resolveList.forEach(function(cb) { 178 | cb(promise.value); 179 | }); 180 | }); 181 | } 182 | fn(resolve) 183 | } 184 | ``` 185 | 我们再用刚次的例子来验证一下: 186 | ```js 187 | new Promise(function(resolve) { 188 | resolve('B'); 189 | }).then(function(res) { 190 | console.log(res); 191 | return 'C' 192 | }).then(function(res) { 193 | console.log(res); 194 | }) 195 | 196 | console.log('A'); 197 | // A 、 B 、 C 198 | ``` 199 | 这个例子验证OK了,接下来我们再验证另一种场景,`then` 里面如果返回的是一个 `Promise` 示例又会是什么样的结果呢? 200 | ```js 201 | new Promise(function(resolve) { 202 | resolve('B'); 203 | }).then(function(res) { 204 | console.log(res); 205 | return new Promise(function(resolve) { 206 | resolve('C') 207 | }); 208 | }).then(function(res) { 209 | console.log(res); 210 | }) 211 | 212 | console.log('A'); 213 | // A、B、Promise对象 214 | ``` 215 | 观察输出结果,又和我们的预期有出入了,我们希望输出的是 `C` ,然而输出了一个`Promise`对象,接下来我们来对 `then` 完善这种场景。 216 | ```js 217 | this.then = function(onFulfilled) { 218 | return new Promise(function(resolve) { 219 | function handle() { 220 | 221 | var returnVal = isFn(onFulfilled) && onFulfilled(promise.value) || promise.value; 222 | // var returnVal = onFulfilled(promise.value); 223 | if (isFn(returnVal.then)) { 224 | returnVal.then(function(res) { 225 | resolve(res) 226 | }) 227 | } else { 228 | resolve(returnVal); 229 | } 230 | } 231 | if ('PENDING' === promise.status) { 232 | promise._resolveList.push(handle); 233 | } else if ('FULFILLED' === promise.status) { 234 | handle(promise.value) 235 | } 236 | }) 237 | } 238 | ``` 239 | 再来验证一下上面的`demo`: 240 | ```js 241 | new Promise(function(resolve) { 242 | resolve('B'); 243 | }).then(function(res) { 244 | console.log(res); 245 | return new Promise(function(resolve) { 246 | resolve('C') 247 | }); 248 | }).then(function(res) { 249 | console.log(res); 250 | }) 251 | 252 | console.log('A'); 253 | // A、B、C 254 | ``` 255 | 256 | ### 处理失败 257 | 上面介绍了成功时会将 `pending` 状态置为 `fulfilled` ,失败时会将 `pending` 置为 `rejected`,下面来把失败场景的代码补上: 258 | ```js 259 | function Promise(fn) { 260 | var promise = this; 261 | promise._resolveList = []; 262 | promise._rejectList = []; 263 | promise.status = 'PENDING'; 264 | promise.value = null; 265 | promise.reason = null; 266 | 267 | this.then = function(onFulfilled, onRejected) { 268 | return new Promise(function(resolve, reject) { 269 | function handle() { 270 | 271 | var returnVal = isFn(onFulfilled) && onFulfilled(promise.value) || promise.value; 272 | // var returnVal = onFulfilled(promise.value); 273 | if (isFn(returnVal.then)) { 274 | returnVal.then(function(res) { 275 | resolve(res) 276 | }) 277 | } else { 278 | resolve(returnVal); 279 | } 280 | } 281 | 282 | function errback(reason) { 283 | reason = isFn(onRejected) && onRejected(promise.reason) || promise.reason; 284 | reject(reason); 285 | } 286 | if ('PENDING' === promise.status) { 287 | promise._resolveList.push(handle); 288 | promise._rejectList.push(errback); 289 | } else if ('FULFILLED' === promise.status) { 290 | handle(promise.value) 291 | } else if ('FULFILLED' === promise.status) { 292 | errback(promise.reason) 293 | } 294 | }) 295 | } 296 | 297 | function isFn(fn) { 298 | return typeof fn === 'function' 299 | } 300 | 301 | function resolve(value) { 302 | setTimeout(function() { 303 | promise.status = 'FULFILLED'; 304 | promise.value = value; 305 | promise._resolveList.forEach(function(cb) { 306 | cb(promise.value); 307 | }); 308 | }); 309 | } 310 | 311 | function reject(reason) { 312 | setTimeout(function() { 313 | promise.status = 'REJECTED'; 314 | promise.reason = reason; 315 | promise._rejectList.forEach(function(cb) { 316 | cb(promise.reason); 317 | }); 318 | }); 319 | } 320 | fn(resolve, reject) 321 | } 322 | ``` 323 | 324 | 到这里`Promise`的实现原理就over了,下面来讲一下`Promise.resolve`、`Promise.reject`、`catch`等`api`。 325 | 326 | ### `Promise.resolve` 327 | ```js 328 | Promise.resolve = function(value){ 329 | return new Promise(function(resolve, reject){ 330 | resolve(value) 331 | }) 332 | } 333 | ``` 334 | 335 | ### `Promise.reject` 336 | ```js 337 | Promise.reject = function(value){ 338 | return Promise(function(resolve, reject){ 339 | reject(value) 340 | }) 341 | } 342 | ``` 343 | 344 | ### `catch` 345 | 在[Promise介绍篇](https://github.com/func-star/promise/wiki/Promise%E4%BB%8B%E7%BB%8D%E7%AF%87)中讲到过,`reject` 和 `catch` 并非完全等价,`catch`不仅能捕获到 `Promise` 的处理错误,而且还能捕获到 `resolve` 执行过程中的报错信息。实际上 `catch` 是通过在`Promise` 中加了一层`then`而间接的达到这种效果。 346 | ```js 347 | this.catch = function(onRejected){ 348 | return this.then(undefined, onRejected) 349 | } 350 | ``` 351 | -------------------------------------------------------------------------------- /source/_posts/Promise实战.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Promise实战 3 | date: 2018-06-26 20:04:41 4 | tags: 5 | --- 6 | 7 | ### 一、概述 8 | 9 | 1. `Promise` 简单来说就是一个对象,他拥有三种状态`pending`、`fulfilled`和`rejected`(过程中、成功和失败)。我们可以简单理解 `Promise` 为一个过程,它不受外界因素干扰,任何其他操作都不能强行改变 `Promise` 的状态。 10 | 2.`Promise` 的状态只会从 `pending` 到 `fulfilled` 或者 `pending` 到 `rejected`,简单的说就是一个处理成功的过程和一个处理失败的过程,而且一旦得到结果,状态就不能改变。 11 | 12 | 13 | ### 二、举例说明 14 | 注:下面会有很多模拟异步数据返回的形式,这里先封一个公共函数供下面的`demo`使用: 15 | ```js 16 | var ajaxDataFn = function(val, delay) { 17 | return new Promise(function(resolve) { 18 | setTimeout(function() { 19 | resolve({ val: val, delay: delay }) 20 | }, delay) 21 | }) 22 | } 23 | ``` 24 | 25 | (1)`Promise` 实例化后会立马执行,状态变化后会触发`then`提前注册好的回调函数(包括成功回调和失败回调) 26 | 27 | ```js 28 | var promise = new Promise((resolve, reject) => { 29 | console.log('step1'); 30 | resolve(); 31 | }); 32 | promise.then(() => { 33 | console.log('Resolved.'); 34 | }) 35 | console.log('Hi!') 36 | // step1 37 | // Hi! 38 | // Resolved 39 | 40 | ``` 41 | 42 | (2)`.then()`的链式调用写法 43 | 44 | (层级较深) 45 | 46 | ```js 47 | ajaxDataFn('test1', 500).then(function(res) { 48 | console.log(res.val); 49 | ajaxDataFn(`${res.val} test2`, 1000).then(function(res) { 50 | console.log(res.val); 51 | ajaxDataFn(`${res.val} test3`, 1500).then(function(res) { 52 | console.log(res.val); 53 | }) 54 | }) 55 | }) 56 | // test1 57 | // test1 test2 58 | // test1 test2 test3 59 | ``` 60 | (建议的写法) 61 | 62 | ```js 63 | ajaxDataFn('test1', 500).then(function(res) { 64 | console.log(res.val); 65 | return ajaxDataFn(`${res.val} test2`, 1000) 66 | }).then(function(res) { 67 | console.log(res.val); 68 | return ajaxDataFn(`${res.val} test3`, 1500) 69 | }).then(function(res) { 70 | console.log(res.val); 71 | }) 72 | // test1 73 | // test1 test2 74 | // test1 test2 test3 75 | ``` 76 | 两种写法都能达到逻辑上的目的,但是用这种链式的写法就能很好的避免掉层级过深的问题,逻辑也能更加清晰,偶合度也低。 77 | 78 | (3)`.catch()`的使用 79 | 80 | demo1: 81 | ```js 82 | var promise = new Promise((resolve, reject) => { 83 | throw new Error('error'); 84 | }); 85 | promise.catch(err => console.log("error: ", err)); 86 | // error: Error: error 87 | ``` 88 | demo2: 89 | 90 | ```js 91 | var promise = new Promise((resolve, reject) => { 92 | reject(new Error('error')); 93 | }); 94 | promise.catch(err => console.log("error: ", err)); 95 | // error: Error: error 96 | ``` 97 | demo3: 98 | 99 | ```js 100 | var promise = new Promise((resolve, reject) => { 101 | throw new Error('error'); 102 | }); 103 | promise.catch(err => { 104 | console.log("error: ", err) 105 | return new Promise((resolve, reject) => { 106 | resolve('catchVal') 107 | }) 108 | }).then(res => { 109 | console.log(res) 110 | }); 111 | // error: Error: error 112 | // catchVal 113 | ``` 114 | 115 | **tip:** `.catch()` 仍然可以返回一个 `Promise` 对象,后面还可以继续 `.then()` 调用 116 | 117 | 118 | (4)`all()`、`race(`)的使用 119 | 可以参考[Promise介绍篇](https://github.com/func-star/promise/wiki/Promise%E4%BB%8B%E7%BB%8D%E7%AF%87)中的demo 120 | 121 | (5)`reject()`、`resolve()`的使用 122 | ```js 123 | Promise.resolve('test').then(function(res) { 124 | console.log(res); 125 | }) 126 | // test 127 | ``` 128 | ```js 129 | Promise.reject('test').then(null, function(res) { 130 | console.log(res); 131 | }) 132 | // test 133 | ``` 134 | ```js 135 | var p = new Promise(function(resolve) { 136 | resolve('test'); 137 | }) 138 | 139 | Promise.resolve(p).then(function(res) { 140 | console.log(res); 141 | }) 142 | // test 143 | ``` 144 | ```js 145 | console.log(p === Promise.resolve(p)) 146 | // true 147 | ``` 148 | **tip:** `Promise.resolve()`会返回一个 `Promise` 示例,它的参数可以是一个值也可以是一个 `Promise` 实例,且当参数是 `Promis` 实例时,`Promise.resolve(p) === p`。因此在真实场景中,当使用第三方库时,别人提供的 `Promise` 实例返回,建议都用 `Promise.resolve()` 包装后再使用,这样是最安全的。哪怕别人的库写的有问题也不会影响我们逻辑的正常运行。 149 | 150 | 151 | ### 三、实战应用 152 | 153 | 先介绍`.then()`的实现简化版原理(可以前往[Promise原理篇](https://github.com/func-star/promise/wiki/Promise%E5%8E%9F%E7%90%86%E7%AF%87)查看) 154 | 155 | ```js 156 | this.then = function(onFulfilled) { 157 | return new Promise(function(resolve) { 158 | function handle() { 159 | 160 | var returnVal = isFn(onFulfilled) && onFulfilled(promise.value) || promise.value; 161 | // var returnVal = onFulfilled(promise.value); 162 | if (isFn(returnVal.then)) { 163 | returnVal.then(function(res) { 164 | resolve(res) 165 | }) 166 | } else { 167 | resolve(returnVal); 168 | } 169 | } 170 | if ('PENDING' === promise.status) { 171 | promise._resolveList.push(handle); 172 | } else if ('FULFILLED' === promise.status) { 173 | handle(promise.value) 174 | } 175 | }) 176 | } 177 | ``` 178 | ================part1================ 179 | 180 | 下面来试一把。。 181 | 182 | ```js 183 | function test1() { 184 | console.log('test1'); 185 | return ajaxDataFn('test1', 1000); 186 | } 187 | 188 | function test2() { 189 | console.log('test2'); 190 | return ajaxDataFn('test2', 1000); 191 | } 192 | 193 | function test3() { 194 | console.log('test3'); 195 | return console.log; 196 | } 197 | 198 | // 题1 199 | test1().then(function() { 200 | return test2(); 201 | }).then(test3); 202 | 203 | // 题2 204 | test1().then(function() { 205 | test2(); 206 | }).then(test3); 207 | 208 | // 题3 209 | test1().then(test2()) 210 | .then(test3); 211 | 212 | // 题4 213 | test1().then(test2) 214 | .then(test3); 215 | ``` 216 | 217 | `test1()` 和 `test2()` 均返回 `promises`。。。这四个题有什么区别呢,执行顺序又是怎样的呢???? 218 | 219 | ===================================== 220 | 221 | ================part2================ 222 | 223 | ```js 224 | ajaxDataFn([1, 2, 3], 500).then(function(res) { 225 | res.val.forEach(function(item) { 226 | ajaxDataFn(item, 500).then(function(res) { 227 | console.log(res) 228 | }); 229 | }) 230 | }).then(function() { 231 | console.log('done') 232 | }) 233 | // done 234 | // {val: 1, delay: 500} 235 | // {val: 2, delay: 500} 236 | // {val: 3, delay: 500} 237 | ``` 238 | 这段代码表达了通过第一个 `Promise` 返回一个数组 `[1,2,3]`,再通过第二个 `Promise` 来将数组的每一个 `item` 输出,最后想输出结束标识。 239 | 然而第一个 `Promis`e 返回的实际上是 `undefined` ,也就是说第二个`.then()`根本不会等到 `list` 中所有的`item`项执行完再去执行。 240 | 241 | 那么`forEach(或者for)`这类的循环又怎么和`Promise`一起来使用呢?我们可以看下上面介绍中提到的将所有的 `list`操作包装成一个新的 `Promise` 去执行。 242 | 243 | ```js 244 | ajaxDataFn([1, 2, 3], 500).then(function(res) { 245 | return Promise.all(res.val.map(function(item) { 246 | return ajaxDataFn(item, 500).then(function(res) { 247 | console.log(res) 248 | }); 249 | })) 250 | }).then(function() { 251 | console.log('done') 252 | }) 253 | // {val: 1, delay: 500} 254 | // {val: 2, delay: 500} 255 | // {val: 3, delay: 500} 256 | // done 257 | ``` 258 | ===================================== 259 | 260 | ================part3================ 261 | 262 | 在 `Promise.all()` 和 `.then()` 聊了那么多点之后,咱进阶的聊一下 `.then()` 的好用的地方 263 | 264 | 看完上述的那么多例子,可以总结出,在then()函数内部可以作3件事。 265 | 266 | 1.return 一个`Promise` 267 | 268 | 2.return 一个同步数据(当然可能是`undefined`) 269 | 270 | 3.throw一个异常 271 | 272 | 先来看下第一点: 273 | 274 | ```js 275 | ajaxDataFn('test1', 500).then(function(res) { 276 | console.log(res.val); 277 | return ajaxDataFn('test2', 500) 278 | }).then(function(res) { 279 | console.log(res.val) 280 | }) 281 | // test1 282 | // test2 283 | ``` 284 | 这是最常用的一种用法,但是千万别忘了`return`这个关键字哦!如果没写,那么下一个函数接收的就是`undefined`了,而且也不会等第一个请求结束了才去执行第二个。 285 | 286 | 看第二点: 287 | 288 | ```js 289 | var cache = null; 290 | ajaxDataFn('test1', 300).then(function(res) { 291 | if (cache) { 292 | console.log('缓存中拉取数据') 293 | return cache; 294 | } 295 | return ajaxDataFn('test2', 300).then(function(res) { 296 | console.log('从test2 Promise中拉取数据') 297 | cache = res; 298 | return cache; 299 | }); 300 | }).then(function(res) { 301 | console.log(res.val) 302 | }) 303 | 304 | ajaxDataFn('test1', 1000).then(function(res) { 305 | if (cache) { 306 | console.log('缓存中拉取数据') 307 | return cache; 308 | } 309 | return ajaxDataFn('test2', 500).then(function(res) { 310 | console.log('从test2 Promise中拉取数据') 311 | cache = res; 312 | return cache; 313 | }); 314 | }).then(function(res) { 315 | console.log(res.val) 316 | }) 317 | // 从test2 Promise中拉取数据 318 | // test2 319 | // 缓存中拉取数据 320 | // test2 321 | ``` 322 | 我们可以用将一些不变的请求数据存在本地变量中,然后下次请求来的时候就直接返回变量中存储的值,这样我们可以节省一些请求消耗。 323 | 324 | 然而这样写存在一个隐患,不知道大家发现没?同步数据就会涉及`undefined`的类型,你很有可能会把`undefined`传到下一个函数,因此在后面加上`catch`去捕获异常。 325 | 326 | ===================================== 327 | 328 | ================part4================ 329 | 330 | 前面讲到`then()`的第二个参数`reject`和`catch()`并非完全等价,下面就举例来说明 331 | 332 | ```js 333 | ajaxDataFn('test1', 300).then(function(res) { 334 | throw new Error('error'); 335 | }, function(res) { 336 | console.log('reject中捕获到了') 337 | console.log(res) 338 | }).catch(function(error) { 339 | console.log('catch中捕获到了') 340 | console.log(error) 341 | }) 342 | // catch中捕获到了 343 | // Error: error 344 | ``` 345 | ```js 346 | ajaxDataFn('test1', 300).then(function(res) { 347 | throw new Error('error'); 348 | }, function(res) { 349 | console.log('reject中捕获到了') 350 | console.log(res) 351 | }).then(null, function(res) { 352 | console.log('下一级reject中捕获到了') 353 | console.log(res) 354 | }) 355 | // 下一级reject中捕获到了 356 | // Error: error 357 | ``` 358 | 359 | 在同级别 `resolve` 中的处理错误,`reject` 是获取不到错误信息的,但是 `catch` 能获取到。然而下一级的 `reject` 也是能捕获到错误的。 360 | 361 | ===================================== 362 | 363 | ================part5================ 364 | 365 | 前面抛出的问题,现在让我们一起来探讨下,是否都能解决了 366 | 367 | ```js 368 | test1().then(function() { 369 | return test2(); 370 | }).then(test3); 371 | ``` 372 | ```js 373 | test1 374 | |-----------------| 375 | test2(undefined) 376 | |------------------| 377 | test3(resultOfTest2) 378 | |------------------| 379 | ``` 380 | 这是典型的 `then()` 中 `return` 另一个 `Promise` 的场景,首先 `test2` 在 `test1` 后执行肯定没问题。 381 | 而且下一个函数`test3()`会等前一个`test2()`请求完之后才执行。 382 | ```js 383 | test1().then(function() { 384 | test2(); 385 | }).then(test3); 386 | ``` 387 | 388 | ```js 389 | test1 390 | |-----------------| 391 | test2(undefined) 392 | |------------------| 393 | test3(undefined) 394 | |------------------| 395 | ``` 396 | 前面提到在 `then()` 中想要返回另一个 `Promise` 的时候千万别忘了`return`关键字,这也是 `then()` 的副作用用法。 397 | 在`test1().then()`中实际返回的是默认值`undefined`,因此 test3 并不会等到 test2 执行结束后才开始执行。 398 | 而 `test2` 在 `test1` 执行完再执行肯定没问题。 399 | ```js 400 | test1().then(test2()) 401 | .then(test3); 402 | ``` 403 | ```js 404 | test1 405 | |-----------------| 406 | test2(undefined) 407 | |---------------------------------| 408 | test3(resultOfTest1) 409 | |------------------| 410 | ``` 411 | 下面的例子详细一些: 412 | ```js 413 | function test2() { 414 | return Promise.resolve('bar'); 415 | } 416 | Promise.resolve('foo').then(test2).then(function(result) { 417 | console.log(result); 418 | }); 419 | //bar 420 | Promise.resolve('foo').then(test2()).then(function(result) { 421 | console.log(result); 422 | }); 423 | //fool 424 | ``` 425 | 426 | 这个知识点我前面没有介绍,在这里我讲一下(可以参考上面给出的`.then()`原理代码来看)。当`then()`中的参数不是一个函数的时候,内部逻辑会立即执行,也就是说在`.then`注册添加回调函数的时候已经执行了,更细致的说在 `Promise` 的状态还是 `pending` 的时候已经执行了 ,而且不会影响整个链路,很多书上称之为 “Promise穿透”,在这个场景中,`test2` 实际返回的是一个 `Promise` 实例不属于函数,所有在 `test1` 执行完之后立马执行 `test3`,而且 `test2` 不会影响整个进度,所以和`test1`同步进行。 427 | 428 | ```js 429 | test1().then(test2) 430 | .then(test3); 431 | ``` 432 | 433 | ```js 434 | test1 435 | |-----------------| 436 | test2(resultOfTest1) 437 | |------------------| 438 | test3(resultOfTest2) 439 | |------------------| 440 | ``` 441 | 这里 `test2` 就像是把 `then()` 中的回调函数抽离到一个命名函数中。 442 | 这样实际上就和第一种情况一样,`then()`中的回调实际`return`了另一个`Promise`。 443 | ```js 444 | function test2Copy() { 445 | return test2() 446 | } 447 | test1().then(test2Copy).then(test3); 448 | ``` 449 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | JSONStream@^1.0.7: 6 | version "1.3.4" 7 | resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.4.tgz#615bb2adb0cd34c8f4c447b5f6512fa1d8f16a2e" 8 | integrity sha512-Y7vfi3I5oMOYIr+WxV8NZxDSwcbNgzdKYsTNInmycOq9bUYwGg9ryu57Wg5NLmCjqdFPNUmpMBo3kSJN9tCbXg== 9 | dependencies: 10 | jsonparse "^1.2.0" 11 | through ">=2.2.7 <3" 12 | 13 | a-sync-waterfall@^1.0.0: 14 | version "1.0.1" 15 | resolved "https://registry.yarnpkg.com/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz#75b6b6aa72598b497a125e7a2770f14f4c8a1fa7" 16 | integrity sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA== 17 | 18 | abbrev@1, abbrev@^1.0.7: 19 | version "1.1.1" 20 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 21 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 22 | 23 | accepts@~1.3.5: 24 | version "1.3.5" 25 | resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" 26 | integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= 27 | dependencies: 28 | mime-types "~2.1.18" 29 | negotiator "0.6.1" 30 | 31 | align-text@^0.1.1, align-text@^0.1.3: 32 | version "0.1.4" 33 | resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" 34 | integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= 35 | dependencies: 36 | kind-of "^3.0.2" 37 | longest "^1.0.1" 38 | repeat-string "^1.5.2" 39 | 40 | amdefine@>=0.0.4: 41 | version "1.0.1" 42 | resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" 43 | integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= 44 | 45 | ansi-regex@^2.0.0: 46 | version "2.1.1" 47 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 48 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 49 | 50 | ansi-regex@^3.0.0: 51 | version "3.0.0" 52 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 53 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 54 | 55 | ansi-styles@^2.2.1: 56 | version "2.2.1" 57 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 58 | integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= 59 | 60 | ansi-styles@^3.2.1: 61 | version "3.2.1" 62 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 63 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 64 | dependencies: 65 | color-convert "^1.9.0" 66 | 67 | anymatch@^1.3.0: 68 | version "1.3.2" 69 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" 70 | integrity sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA== 71 | dependencies: 72 | micromatch "^2.1.5" 73 | normalize-path "^2.0.0" 74 | 75 | anymatch@^2.0.0: 76 | version "2.0.0" 77 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" 78 | integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== 79 | dependencies: 80 | micromatch "^3.1.4" 81 | normalize-path "^2.1.1" 82 | 83 | aproba@^1.0.3: 84 | version "1.2.0" 85 | resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" 86 | integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== 87 | 88 | archy@^1.0.0: 89 | version "1.0.0" 90 | resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" 91 | integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= 92 | 93 | are-we-there-yet@~1.1.2: 94 | version "1.1.5" 95 | resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" 96 | integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== 97 | dependencies: 98 | delegates "^1.0.0" 99 | readable-stream "^2.0.6" 100 | 101 | argparse@^1.0.7: 102 | version "1.0.10" 103 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 104 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 105 | dependencies: 106 | sprintf-js "~1.0.2" 107 | 108 | arr-diff@^2.0.0: 109 | version "2.0.0" 110 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 111 | integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= 112 | dependencies: 113 | arr-flatten "^1.0.1" 114 | 115 | arr-diff@^4.0.0: 116 | version "4.0.0" 117 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" 118 | integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= 119 | 120 | arr-flatten@^1.0.1, arr-flatten@^1.1.0: 121 | version "1.1.0" 122 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" 123 | integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== 124 | 125 | arr-union@^3.1.0: 126 | version "3.1.0" 127 | resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" 128 | integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= 129 | 130 | array-unique@^0.2.1: 131 | version "0.2.1" 132 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 133 | integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= 134 | 135 | array-unique@^0.3.2: 136 | version "0.3.2" 137 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" 138 | integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= 139 | 140 | asap@^2.0.3: 141 | version "2.0.6" 142 | resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" 143 | integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= 144 | 145 | assign-symbols@^1.0.0: 146 | version "1.0.0" 147 | resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" 148 | integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= 149 | 150 | async-each@^1.0.0: 151 | version "1.0.1" 152 | resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" 153 | integrity sha1-GdOGodntxufByF04iu28xW0zYC0= 154 | 155 | async@~0.2.6: 156 | version "0.2.10" 157 | resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" 158 | integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= 159 | 160 | atob@^2.1.1: 161 | version "2.1.2" 162 | resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" 163 | integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== 164 | 165 | balanced-match@^1.0.0: 166 | version "1.0.0" 167 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 168 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 169 | 170 | base@^0.11.1: 171 | version "0.11.2" 172 | resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" 173 | integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== 174 | dependencies: 175 | cache-base "^1.0.1" 176 | class-utils "^0.3.5" 177 | component-emitter "^1.2.1" 178 | define-property "^1.0.0" 179 | isobject "^3.0.1" 180 | mixin-deep "^1.2.0" 181 | pascalcase "^0.1.1" 182 | 183 | basic-auth@~2.0.0: 184 | version "2.0.1" 185 | resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" 186 | integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== 187 | dependencies: 188 | safe-buffer "5.1.2" 189 | 190 | binary-extensions@^1.0.0: 191 | version "1.12.0" 192 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" 193 | integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== 194 | 195 | bluebird@^3.2.2, bluebird@^3.4.0, bluebird@^3.5.1: 196 | version "3.5.2" 197 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" 198 | integrity sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg== 199 | 200 | boolbase@~1.0.0: 201 | version "1.0.0" 202 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" 203 | integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= 204 | 205 | brace-expansion@^1.1.7: 206 | version "1.1.11" 207 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 208 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 209 | dependencies: 210 | balanced-match "^1.0.0" 211 | concat-map "0.0.1" 212 | 213 | braces@^1.8.2: 214 | version "1.8.5" 215 | resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 216 | integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= 217 | dependencies: 218 | expand-range "^1.8.1" 219 | preserve "^0.2.0" 220 | repeat-element "^1.1.2" 221 | 222 | braces@^2.3.0, braces@^2.3.1: 223 | version "2.3.2" 224 | resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" 225 | integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== 226 | dependencies: 227 | arr-flatten "^1.1.0" 228 | array-unique "^0.3.2" 229 | extend-shallow "^2.0.1" 230 | fill-range "^4.0.0" 231 | isobject "^3.0.1" 232 | repeat-element "^1.1.2" 233 | snapdragon "^0.8.1" 234 | snapdragon-node "^2.0.1" 235 | split-string "^3.0.2" 236 | to-regex "^3.0.1" 237 | 238 | browser-fingerprint@0.0.1: 239 | version "0.0.1" 240 | resolved "https://registry.yarnpkg.com/browser-fingerprint/-/browser-fingerprint-0.0.1.tgz#8df3cdca25bf7d5b3542d61545d730053fce604a" 241 | integrity sha1-jfPNyiW/fVs1QtYVRdcwBT/OYEo= 242 | 243 | bytes@3.0.0: 244 | version "3.0.0" 245 | resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" 246 | integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= 247 | 248 | cache-base@^1.0.1: 249 | version "1.0.1" 250 | resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" 251 | integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== 252 | dependencies: 253 | collection-visit "^1.0.0" 254 | component-emitter "^1.2.1" 255 | get-value "^2.0.6" 256 | has-value "^1.0.0" 257 | isobject "^3.0.1" 258 | set-value "^2.0.0" 259 | to-object-path "^0.3.0" 260 | union-value "^1.0.0" 261 | unset-value "^1.0.0" 262 | 263 | camel-case@^3.0.0: 264 | version "3.0.0" 265 | resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" 266 | integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= 267 | dependencies: 268 | no-case "^2.2.0" 269 | upper-case "^1.1.1" 270 | 271 | camelcase@^1.0.2: 272 | version "1.2.1" 273 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" 274 | integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= 275 | 276 | camelcase@^2.0.1: 277 | version "2.1.1" 278 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" 279 | integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= 280 | 281 | center-align@^0.1.1: 282 | version "0.1.3" 283 | resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" 284 | integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= 285 | dependencies: 286 | align-text "^0.1.3" 287 | lazy-cache "^1.0.3" 288 | 289 | chalk@^1.1.1, chalk@^1.1.3: 290 | version "1.1.3" 291 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 292 | integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= 293 | dependencies: 294 | ansi-styles "^2.2.1" 295 | escape-string-regexp "^1.0.2" 296 | has-ansi "^2.0.0" 297 | strip-ansi "^3.0.0" 298 | supports-color "^2.0.0" 299 | 300 | chalk@^2.3.1: 301 | version "2.4.1" 302 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" 303 | integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== 304 | dependencies: 305 | ansi-styles "^3.2.1" 306 | escape-string-regexp "^1.0.5" 307 | supports-color "^5.3.0" 308 | 309 | cheerio@0.22.0: 310 | version "0.22.0" 311 | resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" 312 | integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= 313 | dependencies: 314 | css-select "~1.2.0" 315 | dom-serializer "~0.1.0" 316 | entities "~1.1.1" 317 | htmlparser2 "^3.9.1" 318 | lodash.assignin "^4.0.9" 319 | lodash.bind "^4.1.4" 320 | lodash.defaults "^4.0.1" 321 | lodash.filter "^4.4.0" 322 | lodash.flatten "^4.2.0" 323 | lodash.foreach "^4.3.0" 324 | lodash.map "^4.4.0" 325 | lodash.merge "^4.4.0" 326 | lodash.pick "^4.2.1" 327 | lodash.reduce "^4.4.0" 328 | lodash.reject "^4.4.0" 329 | lodash.some "^4.4.0" 330 | 331 | chokidar@^1.5.2: 332 | version "1.7.0" 333 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" 334 | integrity sha1-eY5ol3gVHIB2tLNg5e3SjNortGg= 335 | dependencies: 336 | anymatch "^1.3.0" 337 | async-each "^1.0.0" 338 | glob-parent "^2.0.0" 339 | inherits "^2.0.1" 340 | is-binary-path "^1.0.0" 341 | is-glob "^2.0.0" 342 | path-is-absolute "^1.0.0" 343 | readdirp "^2.0.0" 344 | optionalDependencies: 345 | fsevents "^1.0.0" 346 | 347 | chokidar@^2.0.0: 348 | version "2.0.4" 349 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" 350 | integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== 351 | dependencies: 352 | anymatch "^2.0.0" 353 | async-each "^1.0.0" 354 | braces "^2.3.0" 355 | glob-parent "^3.1.0" 356 | inherits "^2.0.1" 357 | is-binary-path "^1.0.0" 358 | is-glob "^4.0.0" 359 | lodash.debounce "^4.0.8" 360 | normalize-path "^2.1.1" 361 | path-is-absolute "^1.0.0" 362 | readdirp "^2.0.0" 363 | upath "^1.0.5" 364 | optionalDependencies: 365 | fsevents "^1.2.2" 366 | 367 | chownr@^1.0.1: 368 | version "1.1.1" 369 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" 370 | integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== 371 | 372 | class-utils@^0.3.5: 373 | version "0.3.6" 374 | resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" 375 | integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== 376 | dependencies: 377 | arr-union "^3.1.0" 378 | define-property "^0.2.5" 379 | isobject "^3.0.0" 380 | static-extend "^0.1.1" 381 | 382 | cliui@^2.1.0: 383 | version "2.1.0" 384 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" 385 | integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= 386 | dependencies: 387 | center-align "^0.1.1" 388 | right-align "^0.1.1" 389 | wordwrap "0.0.2" 390 | 391 | cliui@^3.0.3: 392 | version "3.2.0" 393 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" 394 | integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= 395 | dependencies: 396 | string-width "^1.0.1" 397 | strip-ansi "^3.0.1" 398 | wrap-ansi "^2.0.0" 399 | 400 | code-point-at@^1.0.0: 401 | version "1.1.0" 402 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 403 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= 404 | 405 | collection-visit@^1.0.0: 406 | version "1.0.0" 407 | resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" 408 | integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= 409 | dependencies: 410 | map-visit "^1.0.0" 411 | object-visit "^1.0.0" 412 | 413 | color-convert@^1.9.0: 414 | version "1.9.3" 415 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 416 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 417 | dependencies: 418 | color-name "1.1.3" 419 | 420 | color-name@1.1.3: 421 | version "1.1.3" 422 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 423 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 424 | 425 | command-exists@^1.2.0: 426 | version "1.2.7" 427 | resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.7.tgz#16828f0c3ff2b0c58805861ef211b64fc15692a8" 428 | integrity sha512-doWDvhXCcW5LK0cIUWrOQ8oMFXJv3lEQCkJpGVjM8v9SV0uhqYXB943538tEA2CiaWqSyuYUGAm5ezDwEx9xlw== 429 | 430 | component-emitter@^1.2.1: 431 | version "1.2.1" 432 | resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" 433 | integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= 434 | 435 | compressible@~2.0.14: 436 | version "2.0.15" 437 | resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.15.tgz#857a9ab0a7e5a07d8d837ed43fe2defff64fe212" 438 | integrity sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw== 439 | dependencies: 440 | mime-db ">= 1.36.0 < 2" 441 | 442 | compression@^1.7.3: 443 | version "1.7.3" 444 | resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.3.tgz#27e0e176aaf260f7f2c2813c3e440adb9f1993db" 445 | integrity sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg== 446 | dependencies: 447 | accepts "~1.3.5" 448 | bytes "3.0.0" 449 | compressible "~2.0.14" 450 | debug "2.6.9" 451 | on-headers "~1.0.1" 452 | safe-buffer "5.1.2" 453 | vary "~1.1.2" 454 | 455 | concat-map@0.0.1: 456 | version "0.0.1" 457 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 458 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 459 | 460 | connect@^3.6.6: 461 | version "3.6.6" 462 | resolved "https://registry.yarnpkg.com/connect/-/connect-3.6.6.tgz#09eff6c55af7236e137135a72574858b6786f524" 463 | integrity sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ= 464 | dependencies: 465 | debug "2.6.9" 466 | finalhandler "1.1.0" 467 | parseurl "~1.3.2" 468 | utils-merge "1.0.1" 469 | 470 | console-control-strings@^1.0.0, console-control-strings@~1.1.0: 471 | version "1.1.0" 472 | resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" 473 | integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= 474 | 475 | copy-descriptor@^0.1.0: 476 | version "0.1.1" 477 | resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" 478 | integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= 479 | 480 | core-js@^1.1.1: 481 | version "1.2.7" 482 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" 483 | integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= 484 | 485 | core-util-is@~1.0.0: 486 | version "1.0.2" 487 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 488 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 489 | 490 | cross-spawn@^4.0.0: 491 | version "4.0.2" 492 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" 493 | integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= 494 | dependencies: 495 | lru-cache "^4.0.1" 496 | which "^1.2.9" 497 | 498 | css-parse@1.7.x: 499 | version "1.7.0" 500 | resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.7.0.tgz#321f6cf73782a6ff751111390fc05e2c657d8c9b" 501 | integrity sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs= 502 | 503 | css-select@~1.2.0: 504 | version "1.2.0" 505 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" 506 | integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= 507 | dependencies: 508 | boolbase "~1.0.0" 509 | css-what "2.1" 510 | domutils "1.5.1" 511 | nth-check "~1.0.1" 512 | 513 | css-what@2.1: 514 | version "2.1.0" 515 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" 516 | integrity sha1-lGfQMsOM+u+58teVASUwYvh/ob0= 517 | 518 | cuid@~1.3.8: 519 | version "1.3.8" 520 | resolved "https://registry.yarnpkg.com/cuid/-/cuid-1.3.8.tgz#4b875e0969bad764f7ec0706cf44f5fb0831f6b7" 521 | integrity sha1-S4deCWm612T37AcGz0T1+wgx9rc= 522 | dependencies: 523 | browser-fingerprint "0.0.1" 524 | core-js "^1.1.1" 525 | node-fingerprint "0.0.2" 526 | 527 | debug@*: 528 | version "4.0.1" 529 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.0.1.tgz#f9bb36d439b8d1f0dd52d8fb6b46e4ebb8c1cd5b" 530 | integrity sha512-K23FHJ/Mt404FSlp6gSZCevIbTMLX0j3fmHhUEhQ3Wq0FMODW3+cUSoLdy1Gx4polAf4t/lphhmHH35BB8cLYw== 531 | dependencies: 532 | ms "^2.1.1" 533 | 534 | debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: 535 | version "2.6.9" 536 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 537 | integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== 538 | dependencies: 539 | ms "2.0.0" 540 | 541 | decamelize@^1.0.0, decamelize@^1.1.1: 542 | version "1.2.0" 543 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 544 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 545 | 546 | decode-uri-component@^0.2.0: 547 | version "0.2.0" 548 | resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" 549 | integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= 550 | 551 | deep-extend@^0.6.0: 552 | version "0.6.0" 553 | resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" 554 | integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== 555 | 556 | define-property@^0.2.5: 557 | version "0.2.5" 558 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" 559 | integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= 560 | dependencies: 561 | is-descriptor "^0.1.0" 562 | 563 | define-property@^1.0.0: 564 | version "1.0.0" 565 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" 566 | integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= 567 | dependencies: 568 | is-descriptor "^1.0.0" 569 | 570 | define-property@^2.0.2: 571 | version "2.0.2" 572 | resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" 573 | integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== 574 | dependencies: 575 | is-descriptor "^1.0.2" 576 | isobject "^3.0.1" 577 | 578 | delegates@^1.0.0: 579 | version "1.0.0" 580 | resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" 581 | integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= 582 | 583 | depd@~1.1.2: 584 | version "1.1.2" 585 | resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" 586 | integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= 587 | 588 | destroy@~1.0.4: 589 | version "1.0.4" 590 | resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" 591 | integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= 592 | 593 | detect-libc@^1.0.2: 594 | version "1.0.3" 595 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" 596 | integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= 597 | 598 | dom-serializer@0, dom-serializer@~0.1.0: 599 | version "0.1.0" 600 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82" 601 | integrity sha1-BzxpdUbOB4DOI75KKOKT5AvDDII= 602 | dependencies: 603 | domelementtype "~1.1.1" 604 | entities "~1.1.1" 605 | 606 | domelementtype@1, domelementtype@^1.3.0: 607 | version "1.3.0" 608 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.0.tgz#b17aed82e8ab59e52dd9c19b1756e0fc187204c2" 609 | integrity sha1-sXrtguirWeUt2cGbF1bg/BhyBMI= 610 | 611 | domelementtype@~1.1.1: 612 | version "1.1.3" 613 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" 614 | integrity sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs= 615 | 616 | domhandler@^2.3.0: 617 | version "2.4.2" 618 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" 619 | integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== 620 | dependencies: 621 | domelementtype "1" 622 | 623 | domutils@1.5.1: 624 | version "1.5.1" 625 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" 626 | integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= 627 | dependencies: 628 | dom-serializer "0" 629 | domelementtype "1" 630 | 631 | domutils@^1.5.1: 632 | version "1.7.0" 633 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" 634 | integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== 635 | dependencies: 636 | dom-serializer "0" 637 | domelementtype "1" 638 | 639 | ee-first@1.1.1: 640 | version "1.1.1" 641 | resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" 642 | integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= 643 | 644 | ejs@^2.3.4: 645 | version "2.6.1" 646 | resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" 647 | integrity sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ== 648 | 649 | encodeurl@~1.0.1, encodeurl@~1.0.2: 650 | version "1.0.2" 651 | resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" 652 | integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= 653 | 654 | entities@^1.1.1, entities@~1.1.1: 655 | version "1.1.1" 656 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" 657 | integrity sha1-blwtClYhtdra7O+AuQ7ftc13cvA= 658 | 659 | escape-html@~1.0.3: 660 | version "1.0.3" 661 | resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 662 | integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= 663 | 664 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 665 | version "1.0.5" 666 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 667 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 668 | 669 | esprima@^4.0.0: 670 | version "4.0.1" 671 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 672 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 673 | 674 | etag@~1.8.1: 675 | version "1.8.1" 676 | resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 677 | integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= 678 | 679 | expand-brackets@^0.1.4: 680 | version "0.1.5" 681 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 682 | integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= 683 | dependencies: 684 | is-posix-bracket "^0.1.0" 685 | 686 | expand-brackets@^2.1.4: 687 | version "2.1.4" 688 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" 689 | integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= 690 | dependencies: 691 | debug "^2.3.3" 692 | define-property "^0.2.5" 693 | extend-shallow "^2.0.1" 694 | posix-character-classes "^0.1.0" 695 | regex-not "^1.0.0" 696 | snapdragon "^0.8.1" 697 | to-regex "^3.0.1" 698 | 699 | expand-range@^1.8.1: 700 | version "1.8.2" 701 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 702 | integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= 703 | dependencies: 704 | fill-range "^2.1.0" 705 | 706 | extend-shallow@^2.0.1: 707 | version "2.0.1" 708 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" 709 | integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= 710 | dependencies: 711 | is-extendable "^0.1.0" 712 | 713 | extend-shallow@^3.0.0, extend-shallow@^3.0.2: 714 | version "3.0.2" 715 | resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" 716 | integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= 717 | dependencies: 718 | assign-symbols "^1.0.0" 719 | is-extendable "^1.0.1" 720 | 721 | extglob@^0.3.1: 722 | version "0.3.2" 723 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 724 | integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= 725 | dependencies: 726 | is-extglob "^1.0.0" 727 | 728 | extglob@^2.0.4: 729 | version "2.0.4" 730 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" 731 | integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== 732 | dependencies: 733 | array-unique "^0.3.2" 734 | define-property "^1.0.0" 735 | expand-brackets "^2.1.4" 736 | extend-shallow "^2.0.1" 737 | fragment-cache "^0.2.1" 738 | regex-not "^1.0.0" 739 | snapdragon "^0.8.1" 740 | to-regex "^3.0.1" 741 | 742 | filename-regex@^2.0.0: 743 | version "2.0.1" 744 | resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" 745 | integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= 746 | 747 | fill-range@^2.1.0: 748 | version "2.2.4" 749 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" 750 | integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== 751 | dependencies: 752 | is-number "^2.1.0" 753 | isobject "^2.0.0" 754 | randomatic "^3.0.0" 755 | repeat-element "^1.1.2" 756 | repeat-string "^1.5.2" 757 | 758 | fill-range@^4.0.0: 759 | version "4.0.0" 760 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" 761 | integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= 762 | dependencies: 763 | extend-shallow "^2.0.1" 764 | is-number "^3.0.0" 765 | repeat-string "^1.6.1" 766 | to-regex-range "^2.1.0" 767 | 768 | finalhandler@1.1.0: 769 | version "1.1.0" 770 | resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" 771 | integrity sha1-zgtoVbRYU+eRsvzGgARtiCU91/U= 772 | dependencies: 773 | debug "2.6.9" 774 | encodeurl "~1.0.1" 775 | escape-html "~1.0.3" 776 | on-finished "~2.3.0" 777 | parseurl "~1.3.2" 778 | statuses "~1.3.1" 779 | unpipe "~1.0.0" 780 | 781 | for-in@^1.0.1, for-in@^1.0.2: 782 | version "1.0.2" 783 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 784 | integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= 785 | 786 | for-own@^0.1.4: 787 | version "0.1.5" 788 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 789 | integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= 790 | dependencies: 791 | for-in "^1.0.1" 792 | 793 | fragment-cache@^0.2.1: 794 | version "0.2.1" 795 | resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" 796 | integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= 797 | dependencies: 798 | map-cache "^0.2.2" 799 | 800 | fresh@0.5.2: 801 | version "0.5.2" 802 | resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" 803 | integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= 804 | 805 | fs-minipass@^1.2.5: 806 | version "1.2.5" 807 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" 808 | integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== 809 | dependencies: 810 | minipass "^2.2.1" 811 | 812 | fs.realpath@^1.0.0: 813 | version "1.0.0" 814 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 815 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 816 | 817 | fsevents@^1.0.0, fsevents@^1.2.2: 818 | version "1.2.4" 819 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" 820 | integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== 821 | dependencies: 822 | nan "^2.9.2" 823 | node-pre-gyp "^0.10.0" 824 | 825 | gauge@~2.7.3: 826 | version "2.7.4" 827 | resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" 828 | integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= 829 | dependencies: 830 | aproba "^1.0.3" 831 | console-control-strings "^1.0.0" 832 | has-unicode "^2.0.0" 833 | object-assign "^4.1.0" 834 | signal-exit "^3.0.0" 835 | string-width "^1.0.1" 836 | strip-ansi "^3.0.1" 837 | wide-align "^1.1.0" 838 | 839 | get-value@^2.0.3, get-value@^2.0.6: 840 | version "2.0.6" 841 | resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" 842 | integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= 843 | 844 | glob-base@^0.3.0: 845 | version "0.3.0" 846 | resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 847 | integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= 848 | dependencies: 849 | glob-parent "^2.0.0" 850 | is-glob "^2.0.0" 851 | 852 | glob-parent@^2.0.0: 853 | version "2.0.0" 854 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 855 | integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= 856 | dependencies: 857 | is-glob "^2.0.0" 858 | 859 | glob-parent@^3.1.0: 860 | version "3.1.0" 861 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" 862 | integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= 863 | dependencies: 864 | is-glob "^3.1.0" 865 | path-dirname "^1.0.0" 866 | 867 | glob@7.0.x: 868 | version "7.0.6" 869 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" 870 | integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo= 871 | dependencies: 872 | fs.realpath "^1.0.0" 873 | inflight "^1.0.4" 874 | inherits "2" 875 | minimatch "^3.0.2" 876 | once "^1.3.0" 877 | path-is-absolute "^1.0.0" 878 | 879 | glob@^6.0.1: 880 | version "6.0.4" 881 | resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" 882 | integrity sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI= 883 | dependencies: 884 | inflight "^1.0.4" 885 | inherits "2" 886 | minimatch "2 || 3" 887 | once "^1.3.0" 888 | path-is-absolute "^1.0.0" 889 | 890 | glob@^7.0.5: 891 | version "7.1.3" 892 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 893 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 894 | dependencies: 895 | fs.realpath "^1.0.0" 896 | inflight "^1.0.4" 897 | inherits "2" 898 | minimatch "^3.0.4" 899 | once "^1.3.0" 900 | path-is-absolute "^1.0.0" 901 | 902 | graceful-fs@^4.1.11, graceful-fs@^4.1.3, graceful-fs@^4.1.4: 903 | version "4.1.11" 904 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 905 | integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= 906 | 907 | has-ansi@^2.0.0: 908 | version "2.0.0" 909 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 910 | integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= 911 | dependencies: 912 | ansi-regex "^2.0.0" 913 | 914 | has-flag@^3.0.0: 915 | version "3.0.0" 916 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 917 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 918 | 919 | has-unicode@^2.0.0: 920 | version "2.0.1" 921 | resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" 922 | integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= 923 | 924 | has-value@^0.3.1: 925 | version "0.3.1" 926 | resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" 927 | integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= 928 | dependencies: 929 | get-value "^2.0.3" 930 | has-values "^0.1.4" 931 | isobject "^2.0.0" 932 | 933 | has-value@^1.0.0: 934 | version "1.0.0" 935 | resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" 936 | integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= 937 | dependencies: 938 | get-value "^2.0.6" 939 | has-values "^1.0.0" 940 | isobject "^3.0.0" 941 | 942 | has-values@^0.1.4: 943 | version "0.1.4" 944 | resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" 945 | integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= 946 | 947 | has-values@^1.0.0: 948 | version "1.0.0" 949 | resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" 950 | integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= 951 | dependencies: 952 | is-number "^3.0.0" 953 | kind-of "^4.0.0" 954 | 955 | hexo-bunyan@^1.0.0: 956 | version "1.0.0" 957 | resolved "https://registry.yarnpkg.com/hexo-bunyan/-/hexo-bunyan-1.0.0.tgz#b2106b26547b232f0195db863cb5d5ff8527fd36" 958 | integrity sha512-RymT8Ck+K77mLt9BEYNb4uyfC7RIQnU5N3laXowMrS28jj2h89VHJCOnhV00mmta4fHRqNa07kP1Hrn17nvMkQ== 959 | optionalDependencies: 960 | moment "^2.10.6" 961 | mv "~2" 962 | safe-json-stringify "~1" 963 | 964 | hexo-cli@^1.1.0: 965 | version "1.1.0" 966 | resolved "https://registry.yarnpkg.com/hexo-cli/-/hexo-cli-1.1.0.tgz#496d238d4646dbfd1cf047b6dc5271bfb5cb798f" 967 | integrity sha512-IWQPppwgmj1iBUcP5mpcMg3Tre6a8Qlr8ejXw6naZiJNSepSgh4mS3KiNPKDa2qQIgPDqJYJzNVFLw+RLA9CkA== 968 | dependencies: 969 | abbrev "^1.0.7" 970 | bluebird "^3.4.0" 971 | chalk "^1.1.3" 972 | command-exists "^1.2.0" 973 | hexo-fs "^0.2.0" 974 | hexo-log "^0.2.0" 975 | hexo-util "^0.6.0" 976 | minimist "^1.2.0" 977 | object-assign "^4.1.0" 978 | resolve "^1.5.0" 979 | tildify "^1.2.0" 980 | 981 | hexo-front-matter@^0.2.2: 982 | version "0.2.3" 983 | resolved "https://registry.yarnpkg.com/hexo-front-matter/-/hexo-front-matter-0.2.3.tgz#c7ca8ef420ea36bd85e8408a2e8c9bf49efa605e" 984 | integrity sha1-x8qO9CDqNr2F6ECKLoyb9J76YF4= 985 | dependencies: 986 | js-yaml "^3.6.1" 987 | 988 | hexo-fs@^0.2.0: 989 | version "0.2.3" 990 | resolved "https://registry.yarnpkg.com/hexo-fs/-/hexo-fs-0.2.3.tgz#c3a81b46e457dfafc56d87c78ef114104f4a3e41" 991 | integrity sha512-rLB1rMVUW3csAljvJgHfyjemL0BrmcUZfBf9hJe6S0pA53igFa3ON0PFwomvoLs1Wdmjs9Awnw9Tru4PjWFSlQ== 992 | dependencies: 993 | bluebird "^3.4.0" 994 | chokidar "^1.5.2" 995 | escape-string-regexp "^1.0.5" 996 | graceful-fs "^4.1.4" 997 | 998 | hexo-generator-archive@^0.1.5: 999 | version "0.1.5" 1000 | resolved "https://registry.yarnpkg.com/hexo-generator-archive/-/hexo-generator-archive-0.1.5.tgz#a979214cdddee2693e0551809c294bedadbb69b3" 1001 | integrity sha512-jPbMtibqkJnAX3hCwhYhK3r6cqy9OKQsVEScjk7LDok+iPmFmkKCNdU/OccxGe1CWAZpT+ta4+LknwNeHG2G4w== 1002 | dependencies: 1003 | hexo-pagination "0.0.2" 1004 | object-assign "^2.0.0" 1005 | 1006 | hexo-generator-category@^0.1.3: 1007 | version "0.1.3" 1008 | resolved "https://registry.yarnpkg.com/hexo-generator-category/-/hexo-generator-category-0.1.3.tgz#b9e6a5862530a83bdd7da4c819c1b9f3e4ccb4b2" 1009 | integrity sha1-uealhiUwqDvdfaTIGcG58+TMtLI= 1010 | dependencies: 1011 | hexo-pagination "0.0.2" 1012 | object-assign "^2.0.0" 1013 | 1014 | hexo-generator-index@^0.2.1: 1015 | version "0.2.1" 1016 | resolved "https://registry.yarnpkg.com/hexo-generator-index/-/hexo-generator-index-0.2.1.tgz#9042229fcac79aaf700575da19332bf3f7ee5c5d" 1017 | integrity sha1-kEIin8rHmq9wBXXaGTMr8/fuXF0= 1018 | dependencies: 1019 | hexo-pagination "0.0.2" 1020 | object-assign "^4.0.1" 1021 | 1022 | hexo-generator-tag@^0.2.0: 1023 | version "0.2.0" 1024 | resolved "https://registry.yarnpkg.com/hexo-generator-tag/-/hexo-generator-tag-0.2.0.tgz#c5715846bb41e57d9c20c1d66d7db21a1abf7a62" 1025 | integrity sha1-xXFYRrtB5X2cIMHWbX2yGhq/emI= 1026 | dependencies: 1027 | hexo-pagination "0.0.2" 1028 | object-assign "^4.0.1" 1029 | 1030 | hexo-i18n@^0.2.1: 1031 | version "0.2.1" 1032 | resolved "https://registry.yarnpkg.com/hexo-i18n/-/hexo-i18n-0.2.1.tgz#84f141432bf09d8b558ed878c728164b6d1cd6de" 1033 | integrity sha1-hPFBQyvwnYtVjth4xygWS20c1t4= 1034 | dependencies: 1035 | sprintf-js "^1.0.2" 1036 | 1037 | hexo-log@^0.2.0: 1038 | version "0.2.0" 1039 | resolved "https://registry.yarnpkg.com/hexo-log/-/hexo-log-0.2.0.tgz#d30fd45e1a12a83c88033586640485efc5df5a6f" 1040 | integrity sha512-fzoc+GQexxPPILTjoOQILnA3ZG2MFgqMBVel4xvJ11pXptw9+f97ynTgDAExXafyp9Nz2ChXRuqlCYgPtZSlxQ== 1041 | dependencies: 1042 | chalk "^1.1.1" 1043 | hexo-bunyan "^1.0.0" 1044 | 1045 | hexo-pagination@0.0.2: 1046 | version "0.0.2" 1047 | resolved "https://registry.yarnpkg.com/hexo-pagination/-/hexo-pagination-0.0.2.tgz#8cf470c7db0de5b18a3926a76deb194015df7f2b" 1048 | integrity sha1-jPRwx9sN5bGKOSanbesZQBXffys= 1049 | dependencies: 1050 | utils-merge "^1.0.0" 1051 | 1052 | hexo-renderer-ejs@^0.3.1: 1053 | version "0.3.1" 1054 | resolved "https://registry.yarnpkg.com/hexo-renderer-ejs/-/hexo-renderer-ejs-0.3.1.tgz#c0c1a3757532d47e5b7d9dc908b5dfd98c94be2c" 1055 | integrity sha512-XN8pYJU+Wr3dT8ipqEPRlOBySJpd1C5NUBBzgZpVSVBC/6L36O0YZI/Qd5NxQqwfGfSuKQ8N5iMyjmRXSR1MdA== 1056 | dependencies: 1057 | ejs "^2.3.4" 1058 | object-assign "^4.0.1" 1059 | 1060 | hexo-renderer-marked@^0.3.2: 1061 | version "0.3.2" 1062 | resolved "https://registry.yarnpkg.com/hexo-renderer-marked/-/hexo-renderer-marked-0.3.2.tgz#d6a37af9ff195e30f9ef6ede1a06ea1fe4322966" 1063 | integrity sha512-joSLeHB0YRkuViIPQlRz4A+zfJKPNHT+rABFgPHiT1zL9eeTUPxoLL4h7kcgOwRLAontVScaxP2Sie15mNitFg== 1064 | dependencies: 1065 | hexo-util "^0.6.2" 1066 | marked "^0.3.9" 1067 | object-assign "^4.1.1" 1068 | strip-indent "^2.0.0" 1069 | 1070 | hexo-renderer-stylus@^0.3.3: 1071 | version "0.3.3" 1072 | resolved "https://registry.yarnpkg.com/hexo-renderer-stylus/-/hexo-renderer-stylus-0.3.3.tgz#c54ea27e1fd8e3c8a9a7a84cfba8ad354122ca7f" 1073 | integrity sha1-xU6ifh/Y48ipp6hM+6itNUEiyn8= 1074 | dependencies: 1075 | nib "^1.1.2" 1076 | stylus "^0.54.5" 1077 | 1078 | hexo-server@^0.3.1: 1079 | version "0.3.3" 1080 | resolved "https://registry.yarnpkg.com/hexo-server/-/hexo-server-0.3.3.tgz#b86712974920bfcc3057debbdb35dd1be6c30080" 1081 | integrity sha512-70zQaf4Z+bj37Kvq7tEyn9WHH+Xj7uqbvOlGp8pHaOzWLp/riX3rMq3nnQKA2P8dKkBaM0/72IqjJPWu2Zt2WA== 1082 | dependencies: 1083 | bluebird "^3.5.1" 1084 | chalk "^1.1.3" 1085 | compression "^1.7.3" 1086 | connect "^3.6.6" 1087 | mime "^1.6.0" 1088 | morgan "^1.9.0" 1089 | object-assign "^4.1.1" 1090 | opn "^5.3.0" 1091 | serve-static "^1.13.2" 1092 | 1093 | hexo-util@^0.6.0, hexo-util@^0.6.2, hexo-util@^0.6.3: 1094 | version "0.6.3" 1095 | resolved "https://registry.yarnpkg.com/hexo-util/-/hexo-util-0.6.3.tgz#16a2ade457bef955af0dfd22a3fe6f0a49a9137c" 1096 | integrity sha512-zPxaqCWZz3/25SAB4FlrRtWktJ+Pr+vBiv/nyHpXKgXPt1m70liViKlRwWLqDmRjJ72x6/k4qCEeXHajvcGHUw== 1097 | dependencies: 1098 | bluebird "^3.4.0" 1099 | camel-case "^3.0.0" 1100 | cross-spawn "^4.0.0" 1101 | highlight.js "^9.4.0" 1102 | html-entities "^1.2.0" 1103 | striptags "^2.1.1" 1104 | 1105 | hexo@^3.7.0: 1106 | version "3.7.1" 1107 | resolved "https://registry.yarnpkg.com/hexo/-/hexo-3.7.1.tgz#0381874e67891b521b9e3023ef4db85a62337f96" 1108 | integrity sha512-+RRN4C8oWYzEnW0NtqNrIfIITRTvXpMoE6OrK5aK4nrO+4lzp0JfZkoxnsINVXUPmzHRimLWUzO95x9lt33jEg== 1109 | dependencies: 1110 | abbrev "^1.0.7" 1111 | archy "^1.0.0" 1112 | bluebird "^3.4.0" 1113 | chalk "^2.3.1" 1114 | cheerio "0.22.0" 1115 | hexo-cli "^1.1.0" 1116 | hexo-front-matter "^0.2.2" 1117 | hexo-fs "^0.2.0" 1118 | hexo-i18n "^0.2.1" 1119 | hexo-log "^0.2.0" 1120 | hexo-util "^0.6.3" 1121 | js-yaml "^3.6.1" 1122 | lodash "^4.17.5" 1123 | minimatch "^3.0.4" 1124 | moment "^2.19.4" 1125 | moment-timezone "^0.5.14" 1126 | nunjucks "^3.1.2" 1127 | pretty-hrtime "^1.0.2" 1128 | resolve "^1.5.0" 1129 | strip-ansi "^4.0.0" 1130 | strip-indent "^2.0.0" 1131 | swig-extras "0.0.1" 1132 | swig-templates "^2.0.2" 1133 | text-table "^0.2.0" 1134 | tildify "^1.2.0" 1135 | titlecase "^1.1.2" 1136 | warehouse "^2.2.0" 1137 | 1138 | highlight.js@^9.4.0: 1139 | version "9.12.0" 1140 | resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" 1141 | integrity sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4= 1142 | 1143 | html-entities@^1.2.0: 1144 | version "1.2.1" 1145 | resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" 1146 | integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= 1147 | 1148 | htmlparser2@^3.9.1: 1149 | version "3.9.2" 1150 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.9.2.tgz#1bdf87acca0f3f9e53fa4fcceb0f4b4cbb00b338" 1151 | integrity sha1-G9+HrMoPP55T+k/M6w9LTLsAszg= 1152 | dependencies: 1153 | domelementtype "^1.3.0" 1154 | domhandler "^2.3.0" 1155 | domutils "^1.5.1" 1156 | entities "^1.1.1" 1157 | inherits "^2.0.1" 1158 | readable-stream "^2.0.2" 1159 | 1160 | http-errors@~1.6.2: 1161 | version "1.6.3" 1162 | resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" 1163 | integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= 1164 | dependencies: 1165 | depd "~1.1.2" 1166 | inherits "2.0.3" 1167 | setprototypeof "1.1.0" 1168 | statuses ">= 1.4.0 < 2" 1169 | 1170 | iconv-lite@^0.4.4: 1171 | version "0.4.24" 1172 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" 1173 | integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== 1174 | dependencies: 1175 | safer-buffer ">= 2.1.2 < 3" 1176 | 1177 | ignore-walk@^3.0.1: 1178 | version "3.0.1" 1179 | resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" 1180 | integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== 1181 | dependencies: 1182 | minimatch "^3.0.4" 1183 | 1184 | inflight@^1.0.4: 1185 | version "1.0.6" 1186 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 1187 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 1188 | dependencies: 1189 | once "^1.3.0" 1190 | wrappy "1" 1191 | 1192 | inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.3: 1193 | version "2.0.3" 1194 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 1195 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 1196 | 1197 | ini@~1.3.0: 1198 | version "1.3.5" 1199 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" 1200 | integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== 1201 | 1202 | invert-kv@^1.0.0: 1203 | version "1.0.0" 1204 | resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" 1205 | integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= 1206 | 1207 | is-accessor-descriptor@^0.1.6: 1208 | version "0.1.6" 1209 | resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" 1210 | integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= 1211 | dependencies: 1212 | kind-of "^3.0.2" 1213 | 1214 | is-accessor-descriptor@^1.0.0: 1215 | version "1.0.0" 1216 | resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" 1217 | integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== 1218 | dependencies: 1219 | kind-of "^6.0.0" 1220 | 1221 | is-binary-path@^1.0.0: 1222 | version "1.0.1" 1223 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" 1224 | integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= 1225 | dependencies: 1226 | binary-extensions "^1.0.0" 1227 | 1228 | is-buffer@^1.1.5: 1229 | version "1.1.6" 1230 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 1231 | integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== 1232 | 1233 | is-data-descriptor@^0.1.4: 1234 | version "0.1.4" 1235 | resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" 1236 | integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= 1237 | dependencies: 1238 | kind-of "^3.0.2" 1239 | 1240 | is-data-descriptor@^1.0.0: 1241 | version "1.0.0" 1242 | resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" 1243 | integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== 1244 | dependencies: 1245 | kind-of "^6.0.0" 1246 | 1247 | is-descriptor@^0.1.0: 1248 | version "0.1.6" 1249 | resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" 1250 | integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== 1251 | dependencies: 1252 | is-accessor-descriptor "^0.1.6" 1253 | is-data-descriptor "^0.1.4" 1254 | kind-of "^5.0.0" 1255 | 1256 | is-descriptor@^1.0.0, is-descriptor@^1.0.2: 1257 | version "1.0.2" 1258 | resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" 1259 | integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== 1260 | dependencies: 1261 | is-accessor-descriptor "^1.0.0" 1262 | is-data-descriptor "^1.0.0" 1263 | kind-of "^6.0.2" 1264 | 1265 | is-dotfile@^1.0.0: 1266 | version "1.0.3" 1267 | resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" 1268 | integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= 1269 | 1270 | is-equal-shallow@^0.1.3: 1271 | version "0.1.3" 1272 | resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 1273 | integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= 1274 | dependencies: 1275 | is-primitive "^2.0.0" 1276 | 1277 | is-extendable@^0.1.0, is-extendable@^0.1.1: 1278 | version "0.1.1" 1279 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 1280 | integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= 1281 | 1282 | is-extendable@^1.0.1: 1283 | version "1.0.1" 1284 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" 1285 | integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== 1286 | dependencies: 1287 | is-plain-object "^2.0.4" 1288 | 1289 | is-extglob@^1.0.0: 1290 | version "1.0.0" 1291 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 1292 | integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= 1293 | 1294 | is-extglob@^2.1.0, is-extglob@^2.1.1: 1295 | version "2.1.1" 1296 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 1297 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 1298 | 1299 | is-fullwidth-code-point@^1.0.0: 1300 | version "1.0.0" 1301 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 1302 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= 1303 | dependencies: 1304 | number-is-nan "^1.0.0" 1305 | 1306 | is-fullwidth-code-point@^2.0.0: 1307 | version "2.0.0" 1308 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 1309 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 1310 | 1311 | is-glob@^2.0.0, is-glob@^2.0.1: 1312 | version "2.0.1" 1313 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 1314 | integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= 1315 | dependencies: 1316 | is-extglob "^1.0.0" 1317 | 1318 | is-glob@^3.1.0: 1319 | version "3.1.0" 1320 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" 1321 | integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= 1322 | dependencies: 1323 | is-extglob "^2.1.0" 1324 | 1325 | is-glob@^4.0.0: 1326 | version "4.0.0" 1327 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" 1328 | integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= 1329 | dependencies: 1330 | is-extglob "^2.1.1" 1331 | 1332 | is-number@^2.1.0: 1333 | version "2.1.0" 1334 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 1335 | integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= 1336 | dependencies: 1337 | kind-of "^3.0.2" 1338 | 1339 | is-number@^3.0.0: 1340 | version "3.0.0" 1341 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" 1342 | integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= 1343 | dependencies: 1344 | kind-of "^3.0.2" 1345 | 1346 | is-number@^4.0.0: 1347 | version "4.0.0" 1348 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" 1349 | integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== 1350 | 1351 | is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: 1352 | version "2.0.4" 1353 | resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" 1354 | integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== 1355 | dependencies: 1356 | isobject "^3.0.1" 1357 | 1358 | is-posix-bracket@^0.1.0: 1359 | version "0.1.1" 1360 | resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 1361 | integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= 1362 | 1363 | is-primitive@^2.0.0: 1364 | version "2.0.0" 1365 | resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 1366 | integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= 1367 | 1368 | is-windows@^1.0.2: 1369 | version "1.0.2" 1370 | resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" 1371 | integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== 1372 | 1373 | is-wsl@^1.1.0: 1374 | version "1.1.0" 1375 | resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" 1376 | integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= 1377 | 1378 | isarray@1.0.0, isarray@~1.0.0: 1379 | version "1.0.0" 1380 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 1381 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 1382 | 1383 | isexe@^2.0.0: 1384 | version "2.0.0" 1385 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 1386 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 1387 | 1388 | isobject@^2.0.0: 1389 | version "2.1.0" 1390 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 1391 | integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= 1392 | dependencies: 1393 | isarray "1.0.0" 1394 | 1395 | isobject@^3.0.0, isobject@^3.0.1: 1396 | version "3.0.1" 1397 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" 1398 | integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= 1399 | 1400 | js-yaml@^3.6.1: 1401 | version "3.12.0" 1402 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" 1403 | integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== 1404 | dependencies: 1405 | argparse "^1.0.7" 1406 | esprima "^4.0.0" 1407 | 1408 | jsonparse@^1.2.0: 1409 | version "1.3.1" 1410 | resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" 1411 | integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= 1412 | 1413 | kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: 1414 | version "3.2.2" 1415 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 1416 | integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= 1417 | dependencies: 1418 | is-buffer "^1.1.5" 1419 | 1420 | kind-of@^4.0.0: 1421 | version "4.0.0" 1422 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" 1423 | integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= 1424 | dependencies: 1425 | is-buffer "^1.1.5" 1426 | 1427 | kind-of@^5.0.0: 1428 | version "5.1.0" 1429 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" 1430 | integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== 1431 | 1432 | kind-of@^6.0.0, kind-of@^6.0.2: 1433 | version "6.0.2" 1434 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" 1435 | integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== 1436 | 1437 | lazy-cache@^1.0.3: 1438 | version "1.0.4" 1439 | resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" 1440 | integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= 1441 | 1442 | lcid@^1.0.0: 1443 | version "1.0.0" 1444 | resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" 1445 | integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= 1446 | dependencies: 1447 | invert-kv "^1.0.0" 1448 | 1449 | lodash.assignin@^4.0.9: 1450 | version "4.2.0" 1451 | resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" 1452 | integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= 1453 | 1454 | lodash.bind@^4.1.4: 1455 | version "4.2.1" 1456 | resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" 1457 | integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= 1458 | 1459 | lodash.debounce@^4.0.8: 1460 | version "4.0.8" 1461 | resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" 1462 | integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= 1463 | 1464 | lodash.defaults@^4.0.1: 1465 | version "4.2.0" 1466 | resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" 1467 | integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= 1468 | 1469 | lodash.filter@^4.4.0: 1470 | version "4.6.0" 1471 | resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" 1472 | integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= 1473 | 1474 | lodash.flatten@^4.2.0: 1475 | version "4.4.0" 1476 | resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" 1477 | integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= 1478 | 1479 | lodash.foreach@^4.3.0: 1480 | version "4.5.0" 1481 | resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" 1482 | integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= 1483 | 1484 | lodash.map@^4.4.0: 1485 | version "4.6.0" 1486 | resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" 1487 | integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= 1488 | 1489 | lodash.merge@^4.4.0: 1490 | version "4.6.1" 1491 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" 1492 | integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ== 1493 | 1494 | lodash.pick@^4.2.1: 1495 | version "4.4.0" 1496 | resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" 1497 | integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= 1498 | 1499 | lodash.reduce@^4.4.0: 1500 | version "4.6.0" 1501 | resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" 1502 | integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= 1503 | 1504 | lodash.reject@^4.4.0: 1505 | version "4.6.0" 1506 | resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" 1507 | integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= 1508 | 1509 | lodash.some@^4.4.0: 1510 | version "4.6.0" 1511 | resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" 1512 | integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= 1513 | 1514 | lodash@^4.17.5, lodash@^4.2.1: 1515 | version "4.17.11" 1516 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" 1517 | integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== 1518 | 1519 | longest@^1.0.1: 1520 | version "1.0.1" 1521 | resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" 1522 | integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= 1523 | 1524 | lower-case@^1.1.1: 1525 | version "1.1.4" 1526 | resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" 1527 | integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= 1528 | 1529 | lru-cache@^4.0.1: 1530 | version "4.1.3" 1531 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" 1532 | integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== 1533 | dependencies: 1534 | pseudomap "^1.0.2" 1535 | yallist "^2.1.2" 1536 | 1537 | map-cache@^0.2.2: 1538 | version "0.2.2" 1539 | resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" 1540 | integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= 1541 | 1542 | map-visit@^1.0.0: 1543 | version "1.0.0" 1544 | resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" 1545 | integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= 1546 | dependencies: 1547 | object-visit "^1.0.0" 1548 | 1549 | markdown@~0.5.0: 1550 | version "0.5.0" 1551 | resolved "https://registry.yarnpkg.com/markdown/-/markdown-0.5.0.tgz#28205b565a8ae7592de207463d6637dc182722b2" 1552 | integrity sha1-KCBbVlqK51kt4gdGPWY33BgnIrI= 1553 | dependencies: 1554 | nopt "~2.1.1" 1555 | 1556 | marked@^0.3.9: 1557 | version "0.3.19" 1558 | resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790" 1559 | integrity sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg== 1560 | 1561 | math-random@^1.0.1: 1562 | version "1.0.1" 1563 | resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" 1564 | integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= 1565 | 1566 | micromatch@^2.1.5: 1567 | version "2.3.11" 1568 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 1569 | integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= 1570 | dependencies: 1571 | arr-diff "^2.0.0" 1572 | array-unique "^0.2.1" 1573 | braces "^1.8.2" 1574 | expand-brackets "^0.1.4" 1575 | extglob "^0.3.1" 1576 | filename-regex "^2.0.0" 1577 | is-extglob "^1.0.0" 1578 | is-glob "^2.0.1" 1579 | kind-of "^3.0.2" 1580 | normalize-path "^2.0.1" 1581 | object.omit "^2.0.0" 1582 | parse-glob "^3.0.4" 1583 | regex-cache "^0.4.2" 1584 | 1585 | micromatch@^3.1.10, micromatch@^3.1.4: 1586 | version "3.1.10" 1587 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" 1588 | integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== 1589 | dependencies: 1590 | arr-diff "^4.0.0" 1591 | array-unique "^0.3.2" 1592 | braces "^2.3.1" 1593 | define-property "^2.0.2" 1594 | extend-shallow "^3.0.2" 1595 | extglob "^2.0.4" 1596 | fragment-cache "^0.2.1" 1597 | kind-of "^6.0.2" 1598 | nanomatch "^1.2.9" 1599 | object.pick "^1.3.0" 1600 | regex-not "^1.0.0" 1601 | snapdragon "^0.8.1" 1602 | to-regex "^3.0.2" 1603 | 1604 | "mime-db@>= 1.36.0 < 2", mime-db@~1.36.0: 1605 | version "1.36.0" 1606 | resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" 1607 | integrity sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw== 1608 | 1609 | mime-types@~2.1.18: 1610 | version "2.1.20" 1611 | resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" 1612 | integrity sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A== 1613 | dependencies: 1614 | mime-db "~1.36.0" 1615 | 1616 | mime@1.4.1: 1617 | version "1.4.1" 1618 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" 1619 | integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== 1620 | 1621 | mime@^1.6.0: 1622 | version "1.6.0" 1623 | resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" 1624 | integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== 1625 | 1626 | "minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.4: 1627 | version "3.0.4" 1628 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1629 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 1630 | dependencies: 1631 | brace-expansion "^1.1.7" 1632 | 1633 | minimist@0.0.8: 1634 | version "0.0.8" 1635 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 1636 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 1637 | 1638 | minimist@^1.2.0: 1639 | version "1.2.0" 1640 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 1641 | integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= 1642 | 1643 | minimist@~0.0.1: 1644 | version "0.0.10" 1645 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" 1646 | integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= 1647 | 1648 | minipass@^2.2.1, minipass@^2.3.3: 1649 | version "2.3.4" 1650 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.4.tgz#4768d7605ed6194d6d576169b9e12ef71e9d9957" 1651 | integrity sha512-mlouk1OHlaUE8Odt1drMtG1bAJA4ZA6B/ehysgV0LUIrDHdKgo1KorZq3pK0b/7Z7LJIQ12MNM6aC+Tn6lUZ5w== 1652 | dependencies: 1653 | safe-buffer "^5.1.2" 1654 | yallist "^3.0.0" 1655 | 1656 | minizlib@^1.1.0: 1657 | version "1.1.0" 1658 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" 1659 | integrity sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA== 1660 | dependencies: 1661 | minipass "^2.2.1" 1662 | 1663 | mixin-deep@^1.2.0: 1664 | version "1.3.1" 1665 | resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" 1666 | integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== 1667 | dependencies: 1668 | for-in "^1.0.2" 1669 | is-extendable "^1.0.1" 1670 | 1671 | mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: 1672 | version "0.5.1" 1673 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 1674 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 1675 | dependencies: 1676 | minimist "0.0.8" 1677 | 1678 | moment-timezone@^0.5.14: 1679 | version "0.5.21" 1680 | resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.21.tgz#3cba247d84492174dbf71de2a9848fa13207b845" 1681 | integrity sha512-j96bAh4otsgj3lKydm3K7kdtA3iKf2m6MY2iSYCzCm5a1zmHo1g+aK3068dDEeocLZQIS9kU8bsdQHLqEvgW0A== 1682 | dependencies: 1683 | moment ">= 2.9.0" 1684 | 1685 | "moment@>= 2.9.0", moment@^2.10.6, moment@^2.19.4: 1686 | version "2.22.2" 1687 | resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" 1688 | integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= 1689 | 1690 | morgan@^1.9.0: 1691 | version "1.9.1" 1692 | resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" 1693 | integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA== 1694 | dependencies: 1695 | basic-auth "~2.0.0" 1696 | debug "2.6.9" 1697 | depd "~1.1.2" 1698 | on-finished "~2.3.0" 1699 | on-headers "~1.0.1" 1700 | 1701 | ms@2.0.0: 1702 | version "2.0.0" 1703 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1704 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 1705 | 1706 | ms@^2.1.1: 1707 | version "2.1.1" 1708 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 1709 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 1710 | 1711 | mv@~2: 1712 | version "2.1.1" 1713 | resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" 1714 | integrity sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI= 1715 | dependencies: 1716 | mkdirp "~0.5.1" 1717 | ncp "~2.0.0" 1718 | rimraf "~2.4.0" 1719 | 1720 | nan@^2.9.2: 1721 | version "2.11.1" 1722 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" 1723 | integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== 1724 | 1725 | nanomatch@^1.2.9: 1726 | version "1.2.13" 1727 | resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" 1728 | integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== 1729 | dependencies: 1730 | arr-diff "^4.0.0" 1731 | array-unique "^0.3.2" 1732 | define-property "^2.0.2" 1733 | extend-shallow "^3.0.2" 1734 | fragment-cache "^0.2.1" 1735 | is-windows "^1.0.2" 1736 | kind-of "^6.0.2" 1737 | object.pick "^1.3.0" 1738 | regex-not "^1.0.0" 1739 | snapdragon "^0.8.1" 1740 | to-regex "^3.0.1" 1741 | 1742 | ncp@~2.0.0: 1743 | version "2.0.0" 1744 | resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" 1745 | integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= 1746 | 1747 | needle@^2.2.1: 1748 | version "2.2.4" 1749 | resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" 1750 | integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== 1751 | dependencies: 1752 | debug "^2.1.2" 1753 | iconv-lite "^0.4.4" 1754 | sax "^1.2.4" 1755 | 1756 | negotiator@0.6.1: 1757 | version "0.6.1" 1758 | resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" 1759 | integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= 1760 | 1761 | nib@^1.1.2: 1762 | version "1.1.2" 1763 | resolved "https://registry.yarnpkg.com/nib/-/nib-1.1.2.tgz#6a69ede4081b95c0def8be024a4c8ae0c2cbb6c7" 1764 | integrity sha1-amnt5AgblcDe+L4CSkyK4MLLtsc= 1765 | dependencies: 1766 | stylus "0.54.5" 1767 | 1768 | no-case@^2.2.0: 1769 | version "2.3.2" 1770 | resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" 1771 | integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== 1772 | dependencies: 1773 | lower-case "^1.1.1" 1774 | 1775 | node-fingerprint@0.0.2: 1776 | version "0.0.2" 1777 | resolved "https://registry.yarnpkg.com/node-fingerprint/-/node-fingerprint-0.0.2.tgz#31cbabeb71a67ae7dd5a7dc042e51c3c75868501" 1778 | integrity sha1-Mcur63GmeufdWn3AQuUcPHWGhQE= 1779 | 1780 | node-pre-gyp@^0.10.0: 1781 | version "0.10.3" 1782 | resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" 1783 | integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== 1784 | dependencies: 1785 | detect-libc "^1.0.2" 1786 | mkdirp "^0.5.1" 1787 | needle "^2.2.1" 1788 | nopt "^4.0.1" 1789 | npm-packlist "^1.1.6" 1790 | npmlog "^4.0.2" 1791 | rc "^1.2.7" 1792 | rimraf "^2.6.1" 1793 | semver "^5.3.0" 1794 | tar "^4" 1795 | 1796 | nopt@^4.0.1: 1797 | version "4.0.1" 1798 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" 1799 | integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= 1800 | dependencies: 1801 | abbrev "1" 1802 | osenv "^0.1.4" 1803 | 1804 | nopt@~2.1.1: 1805 | version "2.1.2" 1806 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-2.1.2.tgz#6cccd977b80132a07731d6e8ce58c2c8303cf9af" 1807 | integrity sha1-bMzZd7gBMqB3MdbozljCyDA8+a8= 1808 | dependencies: 1809 | abbrev "1" 1810 | 1811 | normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: 1812 | version "2.1.1" 1813 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" 1814 | integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= 1815 | dependencies: 1816 | remove-trailing-separator "^1.0.1" 1817 | 1818 | npm-bundled@^1.0.1: 1819 | version "1.0.5" 1820 | resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" 1821 | integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== 1822 | 1823 | npm-packlist@^1.1.6: 1824 | version "1.1.11" 1825 | resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.11.tgz#84e8c683cbe7867d34b1d357d893ce29e28a02de" 1826 | integrity sha512-CxKlZ24urLkJk+9kCm48RTQ7L4hsmgSVzEk0TLGPzzyuFxD7VNgy5Sl24tOLMzQv773a/NeJ1ce1DKeacqffEA== 1827 | dependencies: 1828 | ignore-walk "^3.0.1" 1829 | npm-bundled "^1.0.1" 1830 | 1831 | npmlog@^4.0.2: 1832 | version "4.1.2" 1833 | resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" 1834 | integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== 1835 | dependencies: 1836 | are-we-there-yet "~1.1.2" 1837 | console-control-strings "~1.1.0" 1838 | gauge "~2.7.3" 1839 | set-blocking "~2.0.0" 1840 | 1841 | nth-check@~1.0.1: 1842 | version "1.0.1" 1843 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4" 1844 | integrity sha1-mSms32KPwsQQmN6rgqxYDPFJquQ= 1845 | dependencies: 1846 | boolbase "~1.0.0" 1847 | 1848 | number-is-nan@^1.0.0: 1849 | version "1.0.1" 1850 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 1851 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 1852 | 1853 | nunjucks@^3.1.2: 1854 | version "3.1.3" 1855 | resolved "https://registry.yarnpkg.com/nunjucks/-/nunjucks-3.1.3.tgz#9a23c844af01c143a0b40f3bdd1212a9d7877260" 1856 | integrity sha512-UtlKKAzg9vdtvURdNy9DjGhiB7qYf2R7Ez+hsucOQG5gYJexSggXSSZ+9IpSDyKOlWu/4rMVPH2oVoANOSqNKA== 1857 | dependencies: 1858 | a-sync-waterfall "^1.0.0" 1859 | asap "^2.0.3" 1860 | postinstall-build "^5.0.1" 1861 | yargs "^3.32.0" 1862 | optionalDependencies: 1863 | chokidar "^2.0.0" 1864 | 1865 | object-assign@^2.0.0: 1866 | version "2.1.1" 1867 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" 1868 | integrity sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo= 1869 | 1870 | object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: 1871 | version "4.1.1" 1872 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1873 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 1874 | 1875 | object-copy@^0.1.0: 1876 | version "0.1.0" 1877 | resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" 1878 | integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= 1879 | dependencies: 1880 | copy-descriptor "^0.1.0" 1881 | define-property "^0.2.5" 1882 | kind-of "^3.0.3" 1883 | 1884 | object-visit@^1.0.0: 1885 | version "1.0.1" 1886 | resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" 1887 | integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= 1888 | dependencies: 1889 | isobject "^3.0.0" 1890 | 1891 | object.omit@^2.0.0: 1892 | version "2.0.1" 1893 | resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 1894 | integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= 1895 | dependencies: 1896 | for-own "^0.1.4" 1897 | is-extendable "^0.1.1" 1898 | 1899 | object.pick@^1.3.0: 1900 | version "1.3.0" 1901 | resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" 1902 | integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= 1903 | dependencies: 1904 | isobject "^3.0.1" 1905 | 1906 | on-finished@~2.3.0: 1907 | version "2.3.0" 1908 | resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" 1909 | integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= 1910 | dependencies: 1911 | ee-first "1.1.1" 1912 | 1913 | on-headers@~1.0.1: 1914 | version "1.0.1" 1915 | resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" 1916 | integrity sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c= 1917 | 1918 | once@^1.3.0: 1919 | version "1.4.0" 1920 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1921 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1922 | dependencies: 1923 | wrappy "1" 1924 | 1925 | opn@^5.3.0: 1926 | version "5.4.0" 1927 | resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" 1928 | integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== 1929 | dependencies: 1930 | is-wsl "^1.1.0" 1931 | 1932 | optimist@~0.6: 1933 | version "0.6.1" 1934 | resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" 1935 | integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= 1936 | dependencies: 1937 | minimist "~0.0.1" 1938 | wordwrap "~0.0.2" 1939 | 1940 | os-homedir@^1.0.0: 1941 | version "1.0.2" 1942 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 1943 | integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= 1944 | 1945 | os-locale@^1.4.0: 1946 | version "1.4.0" 1947 | resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" 1948 | integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= 1949 | dependencies: 1950 | lcid "^1.0.0" 1951 | 1952 | os-tmpdir@^1.0.0: 1953 | version "1.0.2" 1954 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 1955 | integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= 1956 | 1957 | osenv@^0.1.4: 1958 | version "0.1.5" 1959 | resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" 1960 | integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== 1961 | dependencies: 1962 | os-homedir "^1.0.0" 1963 | os-tmpdir "^1.0.0" 1964 | 1965 | parse-glob@^3.0.4: 1966 | version "3.0.4" 1967 | resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 1968 | integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= 1969 | dependencies: 1970 | glob-base "^0.3.0" 1971 | is-dotfile "^1.0.0" 1972 | is-extglob "^1.0.0" 1973 | is-glob "^2.0.0" 1974 | 1975 | parseurl@~1.3.2: 1976 | version "1.3.2" 1977 | resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" 1978 | integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= 1979 | 1980 | pascalcase@^0.1.1: 1981 | version "0.1.1" 1982 | resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" 1983 | integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= 1984 | 1985 | path-dirname@^1.0.0: 1986 | version "1.0.2" 1987 | resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" 1988 | integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= 1989 | 1990 | path-is-absolute@^1.0.0: 1991 | version "1.0.1" 1992 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1993 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1994 | 1995 | path-parse@^1.0.5: 1996 | version "1.0.6" 1997 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" 1998 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== 1999 | 2000 | posix-character-classes@^0.1.0: 2001 | version "0.1.1" 2002 | resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" 2003 | integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= 2004 | 2005 | postinstall-build@^5.0.1: 2006 | version "5.0.3" 2007 | resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7" 2008 | integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg== 2009 | 2010 | preserve@^0.2.0: 2011 | version "0.2.0" 2012 | resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 2013 | integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= 2014 | 2015 | pretty-hrtime@^1.0.2: 2016 | version "1.0.3" 2017 | resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" 2018 | integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= 2019 | 2020 | process-nextick-args@~2.0.0: 2021 | version "2.0.0" 2022 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" 2023 | integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== 2024 | 2025 | pseudomap@^1.0.2: 2026 | version "1.0.2" 2027 | resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 2028 | integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= 2029 | 2030 | randomatic@^3.0.0: 2031 | version "3.1.0" 2032 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.0.tgz#36f2ca708e9e567f5ed2ec01949026d50aa10116" 2033 | integrity sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ== 2034 | dependencies: 2035 | is-number "^4.0.0" 2036 | kind-of "^6.0.0" 2037 | math-random "^1.0.1" 2038 | 2039 | range-parser@~1.2.0: 2040 | version "1.2.0" 2041 | resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" 2042 | integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= 2043 | 2044 | rc@^1.2.7: 2045 | version "1.2.8" 2046 | resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" 2047 | integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== 2048 | dependencies: 2049 | deep-extend "^0.6.0" 2050 | ini "~1.3.0" 2051 | minimist "^1.2.0" 2052 | strip-json-comments "~2.0.1" 2053 | 2054 | readable-stream@^2.0.2, readable-stream@^2.0.6: 2055 | version "2.3.6" 2056 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" 2057 | integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== 2058 | dependencies: 2059 | core-util-is "~1.0.0" 2060 | inherits "~2.0.3" 2061 | isarray "~1.0.0" 2062 | process-nextick-args "~2.0.0" 2063 | safe-buffer "~5.1.1" 2064 | string_decoder "~1.1.1" 2065 | util-deprecate "~1.0.1" 2066 | 2067 | readdirp@^2.0.0: 2068 | version "2.2.1" 2069 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" 2070 | integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== 2071 | dependencies: 2072 | graceful-fs "^4.1.11" 2073 | micromatch "^3.1.10" 2074 | readable-stream "^2.0.2" 2075 | 2076 | regex-cache@^0.4.2: 2077 | version "0.4.4" 2078 | resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" 2079 | integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== 2080 | dependencies: 2081 | is-equal-shallow "^0.1.3" 2082 | 2083 | regex-not@^1.0.0, regex-not@^1.0.2: 2084 | version "1.0.2" 2085 | resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" 2086 | integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== 2087 | dependencies: 2088 | extend-shallow "^3.0.2" 2089 | safe-regex "^1.1.0" 2090 | 2091 | remove-trailing-separator@^1.0.1: 2092 | version "1.1.0" 2093 | resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" 2094 | integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= 2095 | 2096 | repeat-element@^1.1.2: 2097 | version "1.1.3" 2098 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" 2099 | integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== 2100 | 2101 | repeat-string@^1.5.2, repeat-string@^1.6.1: 2102 | version "1.6.1" 2103 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 2104 | integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= 2105 | 2106 | resolve-url@^0.2.1: 2107 | version "0.2.1" 2108 | resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" 2109 | integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= 2110 | 2111 | resolve@^1.5.0: 2112 | version "1.8.1" 2113 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" 2114 | integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== 2115 | dependencies: 2116 | path-parse "^1.0.5" 2117 | 2118 | ret@~0.1.10: 2119 | version "0.1.15" 2120 | resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" 2121 | integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== 2122 | 2123 | right-align@^0.1.1: 2124 | version "0.1.3" 2125 | resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" 2126 | integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= 2127 | dependencies: 2128 | align-text "^0.1.1" 2129 | 2130 | rimraf@^2.6.1: 2131 | version "2.6.2" 2132 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 2133 | integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== 2134 | dependencies: 2135 | glob "^7.0.5" 2136 | 2137 | rimraf@~2.4.0: 2138 | version "2.4.5" 2139 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" 2140 | integrity sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto= 2141 | dependencies: 2142 | glob "^6.0.1" 2143 | 2144 | safe-buffer@5.1.2, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 2145 | version "5.1.2" 2146 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 2147 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 2148 | 2149 | safe-json-stringify@~1: 2150 | version "1.2.0" 2151 | resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" 2152 | integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== 2153 | 2154 | safe-regex@^1.1.0: 2155 | version "1.1.0" 2156 | resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" 2157 | integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= 2158 | dependencies: 2159 | ret "~0.1.10" 2160 | 2161 | "safer-buffer@>= 2.1.2 < 3": 2162 | version "2.1.2" 2163 | resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 2164 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 2165 | 2166 | sax@0.5.x: 2167 | version "0.5.8" 2168 | resolved "https://registry.yarnpkg.com/sax/-/sax-0.5.8.tgz#d472db228eb331c2506b0e8c15524adb939d12c1" 2169 | integrity sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE= 2170 | 2171 | sax@^1.2.4: 2172 | version "1.2.4" 2173 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" 2174 | integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== 2175 | 2176 | semver@^5.3.0: 2177 | version "5.5.1" 2178 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" 2179 | integrity sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw== 2180 | 2181 | send@0.16.2: 2182 | version "0.16.2" 2183 | resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" 2184 | integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== 2185 | dependencies: 2186 | debug "2.6.9" 2187 | depd "~1.1.2" 2188 | destroy "~1.0.4" 2189 | encodeurl "~1.0.2" 2190 | escape-html "~1.0.3" 2191 | etag "~1.8.1" 2192 | fresh "0.5.2" 2193 | http-errors "~1.6.2" 2194 | mime "1.4.1" 2195 | ms "2.0.0" 2196 | on-finished "~2.3.0" 2197 | range-parser "~1.2.0" 2198 | statuses "~1.4.0" 2199 | 2200 | serve-static@^1.13.2: 2201 | version "1.13.2" 2202 | resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" 2203 | integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== 2204 | dependencies: 2205 | encodeurl "~1.0.2" 2206 | escape-html "~1.0.3" 2207 | parseurl "~1.3.2" 2208 | send "0.16.2" 2209 | 2210 | set-blocking@~2.0.0: 2211 | version "2.0.0" 2212 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 2213 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 2214 | 2215 | set-value@^0.4.3: 2216 | version "0.4.3" 2217 | resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" 2218 | integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= 2219 | dependencies: 2220 | extend-shallow "^2.0.1" 2221 | is-extendable "^0.1.1" 2222 | is-plain-object "^2.0.1" 2223 | to-object-path "^0.3.0" 2224 | 2225 | set-value@^2.0.0: 2226 | version "2.0.0" 2227 | resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" 2228 | integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== 2229 | dependencies: 2230 | extend-shallow "^2.0.1" 2231 | is-extendable "^0.1.1" 2232 | is-plain-object "^2.0.3" 2233 | split-string "^3.0.1" 2234 | 2235 | setprototypeof@1.1.0: 2236 | version "1.1.0" 2237 | resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" 2238 | integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== 2239 | 2240 | signal-exit@^3.0.0: 2241 | version "3.0.2" 2242 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" 2243 | integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= 2244 | 2245 | snapdragon-node@^2.0.1: 2246 | version "2.1.1" 2247 | resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" 2248 | integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== 2249 | dependencies: 2250 | define-property "^1.0.0" 2251 | isobject "^3.0.0" 2252 | snapdragon-util "^3.0.1" 2253 | 2254 | snapdragon-util@^3.0.1: 2255 | version "3.0.1" 2256 | resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" 2257 | integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== 2258 | dependencies: 2259 | kind-of "^3.2.0" 2260 | 2261 | snapdragon@^0.8.1: 2262 | version "0.8.2" 2263 | resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" 2264 | integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== 2265 | dependencies: 2266 | base "^0.11.1" 2267 | debug "^2.2.0" 2268 | define-property "^0.2.5" 2269 | extend-shallow "^2.0.1" 2270 | map-cache "^0.2.2" 2271 | source-map "^0.5.6" 2272 | source-map-resolve "^0.5.0" 2273 | use "^3.1.0" 2274 | 2275 | source-map-resolve@^0.5.0: 2276 | version "0.5.2" 2277 | resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" 2278 | integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== 2279 | dependencies: 2280 | atob "^2.1.1" 2281 | decode-uri-component "^0.2.0" 2282 | resolve-url "^0.2.1" 2283 | source-map-url "^0.4.0" 2284 | urix "^0.1.0" 2285 | 2286 | source-map-url@^0.4.0: 2287 | version "0.4.0" 2288 | resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" 2289 | integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= 2290 | 2291 | source-map@0.1.x: 2292 | version "0.1.43" 2293 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" 2294 | integrity sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y= 2295 | dependencies: 2296 | amdefine ">=0.0.4" 2297 | 2298 | source-map@^0.5.6, source-map@~0.5.1: 2299 | version "0.5.7" 2300 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 2301 | integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= 2302 | 2303 | split-string@^3.0.1, split-string@^3.0.2: 2304 | version "3.1.0" 2305 | resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" 2306 | integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== 2307 | dependencies: 2308 | extend-shallow "^3.0.0" 2309 | 2310 | sprintf-js@^1.0.2: 2311 | version "1.1.1" 2312 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c" 2313 | integrity sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw= 2314 | 2315 | sprintf-js@~1.0.2: 2316 | version "1.0.3" 2317 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 2318 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 2319 | 2320 | static-extend@^0.1.1: 2321 | version "0.1.2" 2322 | resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" 2323 | integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= 2324 | dependencies: 2325 | define-property "^0.2.5" 2326 | object-copy "^0.1.0" 2327 | 2328 | "statuses@>= 1.4.0 < 2": 2329 | version "1.5.0" 2330 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" 2331 | integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= 2332 | 2333 | statuses@~1.3.1: 2334 | version "1.3.1" 2335 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" 2336 | integrity sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4= 2337 | 2338 | statuses@~1.4.0: 2339 | version "1.4.0" 2340 | resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" 2341 | integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== 2342 | 2343 | string-width@^1.0.1: 2344 | version "1.0.2" 2345 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 2346 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= 2347 | dependencies: 2348 | code-point-at "^1.0.0" 2349 | is-fullwidth-code-point "^1.0.0" 2350 | strip-ansi "^3.0.0" 2351 | 2352 | "string-width@^1.0.2 || 2": 2353 | version "2.1.1" 2354 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 2355 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 2356 | dependencies: 2357 | is-fullwidth-code-point "^2.0.0" 2358 | strip-ansi "^4.0.0" 2359 | 2360 | string_decoder@~1.1.1: 2361 | version "1.1.1" 2362 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 2363 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 2364 | dependencies: 2365 | safe-buffer "~5.1.0" 2366 | 2367 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 2368 | version "3.0.1" 2369 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 2370 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 2371 | dependencies: 2372 | ansi-regex "^2.0.0" 2373 | 2374 | strip-ansi@^4.0.0: 2375 | version "4.0.0" 2376 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 2377 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 2378 | dependencies: 2379 | ansi-regex "^3.0.0" 2380 | 2381 | strip-indent@^2.0.0: 2382 | version "2.0.0" 2383 | resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" 2384 | integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= 2385 | 2386 | strip-json-comments@~2.0.1: 2387 | version "2.0.1" 2388 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 2389 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 2390 | 2391 | striptags@^2.1.1: 2392 | version "2.2.1" 2393 | resolved "https://registry.yarnpkg.com/striptags/-/striptags-2.2.1.tgz#4c450b708d41b8bf39cf24c49ff234fc6aabfd32" 2394 | integrity sha1-TEULcI1BuL85zyTEn/I0/Gqr/TI= 2395 | 2396 | stylus@0.54.5, stylus@^0.54.5: 2397 | version "0.54.5" 2398 | resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.5.tgz#42b9560931ca7090ce8515a798ba9e6aa3d6dc79" 2399 | integrity sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk= 2400 | dependencies: 2401 | css-parse "1.7.x" 2402 | debug "*" 2403 | glob "7.0.x" 2404 | mkdirp "0.5.x" 2405 | sax "0.5.x" 2406 | source-map "0.1.x" 2407 | 2408 | supports-color@^2.0.0: 2409 | version "2.0.0" 2410 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 2411 | integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= 2412 | 2413 | supports-color@^5.3.0: 2414 | version "5.5.0" 2415 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 2416 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 2417 | dependencies: 2418 | has-flag "^3.0.0" 2419 | 2420 | swig-extras@0.0.1: 2421 | version "0.0.1" 2422 | resolved "https://registry.yarnpkg.com/swig-extras/-/swig-extras-0.0.1.tgz#b503fede372ab9c24c6ac68caf656bcef1872328" 2423 | integrity sha1-tQP+3jcqucJMasaMr2VrzvGHIyg= 2424 | dependencies: 2425 | markdown "~0.5.0" 2426 | 2427 | swig-templates@^2.0.2: 2428 | version "2.0.3" 2429 | resolved "https://registry.yarnpkg.com/swig-templates/-/swig-templates-2.0.3.tgz#6b4c43b462175df2a8da857a2043379ec6ea6fd0" 2430 | integrity sha512-QojPTuZWdpznSZWZDB63/grsZuDwT/7geMeGlftbJXDoYBIZEnTcKvz4iwYDv3SwfPX9/B4RtGRSXNnm3S2wwg== 2431 | dependencies: 2432 | optimist "~0.6" 2433 | uglify-js "2.6.0" 2434 | 2435 | tar@^4: 2436 | version "4.4.6" 2437 | resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.6.tgz#63110f09c00b4e60ac8bcfe1bf3c8660235fbc9b" 2438 | integrity sha512-tMkTnh9EdzxyfW+6GK6fCahagXsnYk6kE6S9Gr9pjVdys769+laCTbodXDhPAjzVtEBazRgP0gYqOjnk9dQzLg== 2439 | dependencies: 2440 | chownr "^1.0.1" 2441 | fs-minipass "^1.2.5" 2442 | minipass "^2.3.3" 2443 | minizlib "^1.1.0" 2444 | mkdirp "^0.5.0" 2445 | safe-buffer "^5.1.2" 2446 | yallist "^3.0.2" 2447 | 2448 | text-table@^0.2.0: 2449 | version "0.2.0" 2450 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 2451 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 2452 | 2453 | "through@>=2.2.7 <3": 2454 | version "2.3.8" 2455 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 2456 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 2457 | 2458 | tildify@^1.2.0: 2459 | version "1.2.0" 2460 | resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" 2461 | integrity sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo= 2462 | dependencies: 2463 | os-homedir "^1.0.0" 2464 | 2465 | titlecase@^1.1.2: 2466 | version "1.1.2" 2467 | resolved "https://registry.yarnpkg.com/titlecase/-/titlecase-1.1.2.tgz#78113d1108086b8326331a3247dea8f5a49ea853" 2468 | integrity sha1-eBE9EQgIa4MmMxoyR96o9aSeqFM= 2469 | 2470 | to-object-path@^0.3.0: 2471 | version "0.3.0" 2472 | resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" 2473 | integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= 2474 | dependencies: 2475 | kind-of "^3.0.2" 2476 | 2477 | to-regex-range@^2.1.0: 2478 | version "2.1.1" 2479 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" 2480 | integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= 2481 | dependencies: 2482 | is-number "^3.0.0" 2483 | repeat-string "^1.6.1" 2484 | 2485 | to-regex@^3.0.1, to-regex@^3.0.2: 2486 | version "3.0.2" 2487 | resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" 2488 | integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== 2489 | dependencies: 2490 | define-property "^2.0.2" 2491 | extend-shallow "^3.0.2" 2492 | regex-not "^1.0.2" 2493 | safe-regex "^1.1.0" 2494 | 2495 | uglify-js@2.6.0: 2496 | version "2.6.0" 2497 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.6.0.tgz#25eaa1cc3550e39410ceefafd1cfbb6b6d15f001" 2498 | integrity sha1-JeqhzDVQ45QQzu+v0c+7a20V8AE= 2499 | dependencies: 2500 | async "~0.2.6" 2501 | source-map "~0.5.1" 2502 | uglify-to-browserify "~1.0.0" 2503 | yargs "~3.10.0" 2504 | 2505 | uglify-to-browserify@~1.0.0: 2506 | version "1.0.2" 2507 | resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" 2508 | integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= 2509 | 2510 | union-value@^1.0.0: 2511 | version "1.0.0" 2512 | resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" 2513 | integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= 2514 | dependencies: 2515 | arr-union "^3.1.0" 2516 | get-value "^2.0.6" 2517 | is-extendable "^0.1.1" 2518 | set-value "^0.4.3" 2519 | 2520 | unpipe@~1.0.0: 2521 | version "1.0.0" 2522 | resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" 2523 | integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= 2524 | 2525 | unset-value@^1.0.0: 2526 | version "1.0.0" 2527 | resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" 2528 | integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= 2529 | dependencies: 2530 | has-value "^0.3.1" 2531 | isobject "^3.0.0" 2532 | 2533 | upath@^1.0.5: 2534 | version "1.1.0" 2535 | resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" 2536 | integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== 2537 | 2538 | upper-case@^1.1.1: 2539 | version "1.1.3" 2540 | resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" 2541 | integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= 2542 | 2543 | urix@^0.1.0: 2544 | version "0.1.0" 2545 | resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" 2546 | integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= 2547 | 2548 | use@^3.1.0: 2549 | version "3.1.1" 2550 | resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" 2551 | integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== 2552 | 2553 | util-deprecate@~1.0.1: 2554 | version "1.0.2" 2555 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 2556 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 2557 | 2558 | utils-merge@1.0.1, utils-merge@^1.0.0: 2559 | version "1.0.1" 2560 | resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 2561 | integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= 2562 | 2563 | vary@~1.1.2: 2564 | version "1.1.2" 2565 | resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" 2566 | integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= 2567 | 2568 | warehouse@^2.2.0: 2569 | version "2.2.0" 2570 | resolved "https://registry.yarnpkg.com/warehouse/-/warehouse-2.2.0.tgz#5d09d64942992be667d8f7c86a09c2b8aea04062" 2571 | integrity sha1-XQnWSUKZK+Zn2PfIagnCuK6gQGI= 2572 | dependencies: 2573 | JSONStream "^1.0.7" 2574 | bluebird "^3.2.2" 2575 | cuid "~1.3.8" 2576 | graceful-fs "^4.1.3" 2577 | is-plain-object "^2.0.1" 2578 | lodash "^4.2.1" 2579 | 2580 | which@^1.2.9: 2581 | version "1.3.1" 2582 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 2583 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 2584 | dependencies: 2585 | isexe "^2.0.0" 2586 | 2587 | wide-align@^1.1.0: 2588 | version "1.1.3" 2589 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 2590 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 2591 | dependencies: 2592 | string-width "^1.0.2 || 2" 2593 | 2594 | window-size@0.1.0: 2595 | version "0.1.0" 2596 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" 2597 | integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= 2598 | 2599 | window-size@^0.1.4: 2600 | version "0.1.4" 2601 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" 2602 | integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= 2603 | 2604 | wordwrap@0.0.2: 2605 | version "0.0.2" 2606 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" 2607 | integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= 2608 | 2609 | wordwrap@~0.0.2: 2610 | version "0.0.3" 2611 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" 2612 | integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= 2613 | 2614 | wrap-ansi@^2.0.0: 2615 | version "2.1.0" 2616 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" 2617 | integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= 2618 | dependencies: 2619 | string-width "^1.0.1" 2620 | strip-ansi "^3.0.1" 2621 | 2622 | wrappy@1: 2623 | version "1.0.2" 2624 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 2625 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 2626 | 2627 | y18n@^3.2.0: 2628 | version "3.2.1" 2629 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" 2630 | integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= 2631 | 2632 | yallist@^2.1.2: 2633 | version "2.1.2" 2634 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 2635 | integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= 2636 | 2637 | yallist@^3.0.0, yallist@^3.0.2: 2638 | version "3.0.2" 2639 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" 2640 | integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= 2641 | 2642 | yargs@^3.32.0: 2643 | version "3.32.0" 2644 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" 2645 | integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= 2646 | dependencies: 2647 | camelcase "^2.0.1" 2648 | cliui "^3.0.3" 2649 | decamelize "^1.1.1" 2650 | os-locale "^1.4.0" 2651 | string-width "^1.0.1" 2652 | window-size "^0.1.4" 2653 | y18n "^3.2.0" 2654 | 2655 | yargs@~3.10.0: 2656 | version "3.10.0" 2657 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" 2658 | integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= 2659 | dependencies: 2660 | camelcase "^1.0.2" 2661 | cliui "^2.1.0" 2662 | decamelize "^1.0.0" 2663 | window-size "0.1.0" 2664 | --------------------------------------------------------------------------------