├── .gitignore ├── LICENSE ├── README.md ├── docs └── api.json ├── examples ├── js │ ├── README.md │ ├── intern.json │ ├── package-lock.json │ ├── package.json │ └── tests │ │ ├── axe.js │ │ ├── data │ │ ├── bad_page.html │ │ └── page.html │ │ └── tenon.js └── ts │ ├── .gitignore │ ├── README.md │ ├── intern.json │ ├── package-lock.json │ ├── package.json │ ├── tests │ ├── axe.ts │ ├── data │ │ ├── bad_page.html │ │ └── page.html │ ├── interfaces.ts │ └── tenon.ts │ └── tsconfig.json ├── intern.json ├── package-lock.json ├── package.json ├── src ├── A11yReporter.ts ├── common.ts ├── index.ts └── services │ ├── _axe.ts │ ├── _tenon.ts │ ├── axe.ts │ └── tenon.ts ├── tests ├── data │ ├── a11y_results.json │ ├── axe_results.json │ ├── bad_fragment.html │ ├── bad_page.html │ ├── good_fragment.html │ ├── good_page.html │ └── tenon_results.json ├── integration │ ├── axe.ts │ └── tenon.ts ├── tsconfig.json ├── unit │ ├── A11yReporter.ts │ ├── axe.ts │ └── tenon.ts └── util.ts ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | _build/ 2 | dist/ 3 | a11y-report.html 4 | node_modules/ 5 | *.tgz 6 | a11y-report/ 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | New BSD License 2 | 3 | © 2016 SitePen, Inc. http://sitepen.com 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | * Neither the name of The Intern nor the names of its contributors may 14 | be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE LISTED COPYRIGHT HOLDERS BE LIABLE FOR ANY 21 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | Released under [Dojo Foundation CLA](http://dojofoundation.org/about/cla). 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # a11y 2 | 3 | Accessibility testing for [Intern](https://theintern.io/) 4 | 5 | [![Intern](https://theintern.io/images/intern-v4.svg)](https://github.com/theintern/intern/) 6 | 7 | ## How it works 8 | 9 | Accessibility testing works by having a scanner check a page or page fragment for rule violations. The most commonly used rules are defined in the W3C's [Web Content Accessibility Guidelines](https://www.w3.org/WAI/intro/wcag.php) (WCAG) and the GSA's [Section 508 Standards](https://www.section508.gov/summary-section508-standards). There are twelve general WCAG guidelines at three levels of success criteria: A, AA, and AAA. Scanners can check for violations at any of the levels, and can typically be configured to only check a subset of rules. 10 | 11 | `a11y` is an addon for [Intern](https://github.com/theintern/intern) that lets users write tests targeting various accessibility testing systems. Currently it supports two scanners, [aXe](https://github.com/dequelabs/axe-core) and [Tenon](https://tenon.io). aXe is a JavaScript application that must be injected into the page being tested. The application is configured and executed, returning a report describing the test results. Tenon is a cloud-based testing service; a user requests that the service test a particular URL or page source, and the service returns a report of the results. 12 | 13 | Both scanners are able to test entire pages and document fragments (or portions of a full page). In all cases, though, the scanners operate on a fully styled DOM. This means that if a user needs to test a single commponent in isolation, they'll need to create a test page with all the styles and supporting code required by the component, and use that page to run accessibility tests on the component. 14 | 15 | Note that because aXe must be injected into a loaded page, it can only be used in functional test suites (i.e., those listed in `functionalSuites` in an Intern config). Tenon makes HTTP calls to an external service and can be used in unit or functional tests. 16 | 17 | ## Installation 18 | 19 | The a11y module should be installed as a peer of Intern. 20 | 21 | ``` 22 | $ npm install intern --save-dev 23 | $ npm install @theintern/a11y --save-dev 24 | ``` 25 | 26 | ## Getting started 27 | 28 | Using either the aXe or Tenon modules is straightforward. The service modules can be accessed from the `services` property on the `@theintern/a11y` module. 29 | 30 | ```js 31 | import { services } from '@theintern/a11y'; 32 | const axe = services.axe; 33 | ``` 34 | 35 | or 36 | 37 | ```js 38 | const axe = require('@theintern/a11y').services.axe; 39 | ``` 40 | 41 | The simplest Tenon test looks like: 42 | 43 | ```js 44 | 'check accessibility'() { 45 | return tenon.check({ 46 | source: 'http://mypage.com' 47 | }); 48 | } 49 | ``` 50 | 51 | Similarly, the simplest aXe test looks like: 52 | 53 | ```js 54 | 'check accessibility'() { 55 | return aXe.check({ 56 | // aXe tests must be run in functional test suites 57 | remote: this.remote, 58 | source: 'page.html' 59 | }); 60 | } 61 | ``` 62 | 63 | aXe may also be used inline in a Leadfoot Command chain: 64 | 65 | ```js 66 | 'check accessibility': function () { 67 | return this.remote 68 | .get('page.html') 69 | .then(aXe.createChecker()); 70 | } 71 | ``` 72 | 73 | In all cases, the check is asynchronous and Promise-based. If the check fails (i.e., accessibility violations are detected), the returned Promise is rejected. 74 | 75 | ## Examples 76 | 77 | The repository contains two example projects that use `a11y`, one written in JavaScript and one written in TypeScript. 78 | 79 | ### JavaScript 80 | 81 | 1. cd into `examples/js` 82 | 2. Run `npm install` 83 | 3. Run `TENON_API_KEY= npm test` 84 | 85 | ### TypeScript 86 | 87 | 1. cd into `examples/ts` 88 | 2. Run `npm install` 89 | 2. Run `npm run build` 90 | 3. Run `TENON_API_KEY= npm test` 91 | 92 | ## API 93 | 94 | Importing the `@theintern/a11y` module will return an object with a `services` property. This property value is an object with `tenon` and `axe` properties. You can also import the service modules directly: 95 | 96 | ```js 97 | import { check } from '@theintern/a11y/services/axe'; 98 | ``` 99 | 100 | ### axe 101 | 102 | The aXe checker must be injected into the page being analyzed, and therefore can only be used in functional test suites. The aXe checker provides two functions, `check` and `createChecker`. 103 | 104 | #### check 105 | 106 | The `check` function performs an accessibility analysis on a given URL using a given Command object (typically `this.remote`). 107 | 108 | ```typescript 109 | check({ 110 | /** LeadFoot Command object */ 111 | remote: Command, 112 | 113 | /** URL to load for testing */ 114 | source: string, 115 | 116 | /** Number of milliseconds to wait before starting test */ 117 | waitFor?: number, 118 | 119 | /** A selector to confine analysis to */ 120 | context?: string 121 | 122 | /** aXe-specific configuration */ 123 | config?: Object, 124 | }): PromiseLike 125 | ``` 126 | 127 | The two required parameters are `remote` and `source`. `remote` is a Leadfoot Command object, generally `this.remote` in a test. `source` is the URL that will be analyzed. 128 | 129 | There are three optional parameters. `waitFor` is a number of milliseconds to wait after a page has loaded before starting the accessibility analysis. `context` is a CSS selector (ID or class name) that can be used to confine analysis to a specific part of a page. The `config` paramter contains [aXe configuration options](https://github.com/dequelabs/axe-core/blob/master/doc/API.md#api-name-axeconfigure). 130 | 131 | #### createChecker 132 | 133 | The `createChecker` function returns a Leadfoot Command helper (a `then` callback). It assumes that a page has already been loaded and is ready to be tested, so it doesn't need a source or Command object. 134 | 135 | ```typescript 136 | createChecker(config?: AxeTestOptions): Command 137 | ``` 138 | 139 | ### tenon 140 | 141 | The Tenon checker works by making requests to a remote cloud service. It can be used in functional or unit test suites. 142 | 143 | #### check 144 | 145 | The tenon `check` function works the same way as the axe module's, and takes a similar argument object. 146 | 147 | ```typescript 148 | check({ 149 | /** An external URL, file name, or a data string */ 150 | source: string, 151 | 152 | /** tenon.io API key */ 153 | apiKey?: string, 154 | 155 | /** Number of milliseconds to wait before starting test */ 156 | waitFor?: number, 157 | 158 | /** Tenon configuration options */ 159 | config?: TenonConfig 160 | }): PromiseLike 161 | ``` 162 | 163 | ### A11yReporter 164 | 165 | The A11yReporter class is an Intern reporter that will write test failure detail reports to a file or directory. The `check` methods will fail if accessibility failures are present, regardless of whether the A11yReporter reporter is in use. This reporter simply outputs more detailed information for any failures that are detected. 166 | 167 | The reporter is loaded as an Intern plugin. It can be configured with a filename, which may name an HTML file, in which case all test reports will be written to a single file, or a directory name, in which case test reports will be written to individual HTML files in the given directory. 168 | 169 | ```js 170 | plugins: [ 171 | { 172 | script: '@theintern/a11y/A11yReporter', 173 | 174 | options: { 175 | // If this is a filename, all failures will be written to the given 176 | // file. If it's a directory name (no extension), each test failure 177 | // report will be written to an individual file in the given directory. 178 | filename: 'somereport.html' 179 | } 180 | } 181 | ] 182 | ``` 183 | 184 | The A11yReporter class also exposes a `writeReport` static method. This method allows accessibility test results to be explicitly written to a file rather than relying on the reporter: 185 | 186 | ```js 187 | return axe.check({ ... }) 188 | .catch(error => { 189 | const results = axe.toA11yResults(error.results); 190 | return A11yReporter.writeReport('some_file.html', results); 191 | }) 192 | ``` 193 | 194 | ## Development 195 | 196 | First, clone this repo. Then: 197 | 198 | ``` 199 | $ npm install 200 | $ npm run build 201 | ``` 202 | 203 | Output will be generated in the `_build/` directory. To clean up, run 204 | 205 | ``` 206 | $ npm run clean 207 | ``` 208 | 209 | To run tests: 210 | 211 | ``` 212 | $ TENON_API_KEY= npm test 213 | ``` 214 | 215 | You can provide standard Intern arguments like `grep=foo`. 216 | 217 | Note that a Tenon API key must be provided to run Tenon self-tests. If no key is provided, the tests will be skipped. 218 | 219 | 220 | ## License 221 | 222 | a11y is offered under the [New BSD license](LICENSE). 223 | 224 | © [SitePen, Inc.](http://sitepen.com) and its [contributors](https://github.com/theintern/intern-a11y/graphs/contributors) 225 | 226 | 227 | 232 | -------------------------------------------------------------------------------- /examples/js/README.md: -------------------------------------------------------------------------------- 1 | # JavaScript example 2 | 3 | Install: 4 | 5 | ``` 6 | npm install 7 | ``` 8 | 9 | Run tests: 10 | 11 | ``` 12 | TENON_API_KEY= npm test 13 | ``` 14 | 15 | Note that a Tenon API key is required to run tenon tests. If you don't have 16 | one, those tests will be skipped. 17 | 18 | A couple of tests are expected to fail. After tests are run, a report will be 19 | generated in `a11y-report/`. 20 | -------------------------------------------------------------------------------- /examples/js/intern.json: -------------------------------------------------------------------------------- 1 | { 2 | "environments": [ 3 | "node", 4 | { "browserName": "chrome", "fixSessionCapabilities": "no-detect" } 5 | ], 6 | "functionalSuites": "tests/axe.js", 7 | "node": { 8 | "suites": "tests/tenon.js" 9 | }, 10 | "filterErrorStack": true, 11 | "plugins": "@theintern/a11y/A11yReporter.js" 12 | } 13 | -------------------------------------------------------------------------------- /examples/js/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "intern-a11y-JS-example", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "@dojo/core": { 7 | "version": "0.1.0", 8 | "resolved": "https://registry.npmjs.org/@dojo/core/-/core-0.1.0.tgz", 9 | "integrity": "sha512-boiwQHfV7idOZfZnDzgLrofS2LA7ELGKjd6tl0/hLBunJ3psozAd4CpNcT7XC00/OPYFIxVHFEpI+FZNlpUgfw==" 10 | }, 11 | "@dojo/has": { 12 | "version": "0.1.0", 13 | "resolved": "https://registry.npmjs.org/@dojo/has/-/has-0.1.0.tgz", 14 | "integrity": "sha512-orYLbYVTcqNpZBmPNRlidUyCn/WuV4jV4JvTAy4Je/zQq9m9Nb8gK+8X7/iOUjSJbP1+vv1ld9Q3932IGC1IyA==" 15 | }, 16 | "@dojo/interfaces": { 17 | "version": "0.1.0", 18 | "resolved": "https://registry.npmjs.org/@dojo/interfaces/-/interfaces-0.1.0.tgz", 19 | "integrity": "sha512-rpBALDc5Ya/+JrlyFvrt7wKGdGA1xq2gSFGce6j3L9meB8tAFYQvs/bx9DDp+CSdpEzzeVZWr8C4FpoUId2New==" 20 | }, 21 | "@dojo/shim": { 22 | "version": "0.1.0", 23 | "resolved": "https://registry.npmjs.org/@dojo/shim/-/shim-0.1.0.tgz", 24 | "integrity": "sha512-008RP8DB175ib26dde7wQWFiYIbSACFaArLdLHYdY/cQLN9s3yVj2Gtp5C/9YoY3Ziy9wA241myOjy6QcVHcWw==" 25 | }, 26 | "@theintern/a11y": { 27 | "version": "file:../../_build/src", 28 | "requires": { 29 | "axe-core": "2.5.0" 30 | }, 31 | "dependencies": { 32 | "axe-core": { 33 | "version": "2.5.0", 34 | "bundled": true 35 | } 36 | } 37 | }, 38 | "@theintern/digdug": { 39 | "version": "2.0.3", 40 | "resolved": "https://registry.npmjs.org/@theintern/digdug/-/digdug-2.0.3.tgz", 41 | "integrity": "sha512-H+XhQeuspFrFgZCn2+rTF0qzmCc6IR2hAW4xCDLUv+20VdMowRQrIwJCYW/nk/YynqKz/p041KNeENajVF5CFg==", 42 | "requires": { 43 | "@dojo/core": "0.1.0", 44 | "@dojo/has": "0.1.0", 45 | "@dojo/interfaces": "0.1.0", 46 | "@dojo/shim": "0.1.0", 47 | "decompress": "4.2.0", 48 | "semver": "5.4.1", 49 | "tslib": "1.8.0" 50 | } 51 | }, 52 | "@theintern/leadfoot": { 53 | "version": "2.0.2", 54 | "resolved": "https://registry.npmjs.org/@theintern/leadfoot/-/leadfoot-2.0.2.tgz", 55 | "integrity": "sha512-WHDp40qrM5BgBHFfeVfdOVVqHV1vCnJeDMobChfD7CYMqW2UHGjsJDgNRW3+xZr/Tek1IsHvfwt+t29iEdNrOg==", 56 | "requires": { 57 | "@dojo/core": "0.1.0", 58 | "@dojo/has": "0.1.0", 59 | "@dojo/interfaces": "0.1.0", 60 | "@dojo/shim": "0.1.0", 61 | "@types/jszip": "0.0.33", 62 | "jszip": "3.1.5", 63 | "tslib": "1.8.0" 64 | } 65 | }, 66 | "@types/babel-types": { 67 | "version": "6.25.1", 68 | "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-6.25.1.tgz", 69 | "integrity": "sha512-7Z6r20+HE0viAFhsW0d/UrC1K2tTlpXzGpNlYm8MmCv8z5PbAacFIshrM/MjlGRa5SBqxu2socpy8FHntwZKng==" 70 | }, 71 | "@types/benchmark": { 72 | "version": "1.0.31", 73 | "resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-1.0.31.tgz", 74 | "integrity": "sha512-F6fVNOkGEkSdo/19yWYOwVKGvzbTeWkR/XQYBKtGBQ9oGRjBN9f/L4aJI4sDcVPJO58Y1CJZN8va9V2BhrZapA==" 75 | }, 76 | "@types/body-parser": { 77 | "version": "1.16.8", 78 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.8.tgz", 79 | "integrity": "sha512-BdN2PXxOFnTXFcyONPW6t0fHjz2fvRZHVMFpaS0wYr+Y8fWEaNOs4V8LEu/fpzQlMx+ahdndgTaGTwPC+J/EeA==", 80 | "requires": { 81 | "@types/express": "4.0.39", 82 | "@types/node": "8.0.53" 83 | } 84 | }, 85 | "@types/chai": { 86 | "version": "4.0.5", 87 | "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.5.tgz", 88 | "integrity": "sha512-ZC4tZU+3rDblhVy9cUQp5u+Zw9M0geGY8tzUQgc+4CMIWQLUFpgvrHhaYrSq1TK2m0DjaYIp9yJPyTHN+qhBZg==" 89 | }, 90 | "@types/charm": { 91 | "version": "1.0.1", 92 | "resolved": "https://registry.npmjs.org/@types/charm/-/charm-1.0.1.tgz", 93 | "integrity": "sha512-F9OalGhk60p/DnACfa1SWtmVTMni0+w9t/qfb5Bu7CsurkEjZFN7Z+ii/VGmYpaViPz7o3tBahRQae9O7skFlQ==", 94 | "requires": { 95 | "@types/node": "8.0.53" 96 | } 97 | }, 98 | "@types/diff": { 99 | "version": "3.2.2", 100 | "resolved": "https://registry.npmjs.org/@types/diff/-/diff-3.2.2.tgz", 101 | "integrity": "sha512-q3zfJvaTroV5BjAAR+peTHEGAAhGrPX0z2EzCzpt2mwFA+qzUn2nigJLqSekXRtdULKmT8am7zjvTMZSapIgHw==" 102 | }, 103 | "@types/express": { 104 | "version": "4.0.39", 105 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.39.tgz", 106 | "integrity": "sha512-dBUam7jEjyuEofigUXCtublUHknRZvcRgITlGsTbFgPvnTwtQUt2NgLakbsf+PsGo/Nupqr3IXCYsOpBpofyrA==", 107 | "requires": { 108 | "@types/body-parser": "1.16.8", 109 | "@types/express-serve-static-core": "4.0.57", 110 | "@types/serve-static": "1.13.1" 111 | } 112 | }, 113 | "@types/express-serve-static-core": { 114 | "version": "4.0.57", 115 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.0.57.tgz", 116 | "integrity": "sha512-QLAHjdLwEICm3thVbXSKRoisjfgMVI4xJH/HU8F385BR2HI7PmM6ax4ELXf8Du6sLmSpySXMYaI+xc//oQ/IFw==", 117 | "requires": { 118 | "@types/node": "8.0.53" 119 | } 120 | }, 121 | "@types/http-errors": { 122 | "version": "1.5.34", 123 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.5.34.tgz", 124 | "integrity": "sha1-1qVvJde5XdBwR2gL+CVjLil5aBU=" 125 | }, 126 | "@types/istanbul-lib-coverage": { 127 | "version": "1.1.0", 128 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz", 129 | "integrity": "sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ==" 130 | }, 131 | "@types/istanbul-lib-hook": { 132 | "version": "1.0.0", 133 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-hook/-/istanbul-lib-hook-1.0.0.tgz", 134 | "integrity": "sha512-+kdaJ8hO/auIGcqPuSbd3cnTSzgM8ZW0zfYFZLP67vCmWkZV4LdC1XOXpMWnlONup+PChJMK8Q/+Qrh7WoxnUQ==" 135 | }, 136 | "@types/istanbul-lib-instrument": { 137 | "version": "1.7.0", 138 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.0.tgz", 139 | "integrity": "sha512-BWj7zRtwVU5KzuYL/zNuVoSvYWIpT02smNMpQwQbJjwEyITEGSKsxVIT4b2bzXCWFMq76ss0sdY/5yw3NwTlIA==", 140 | "requires": { 141 | "@types/babel-types": "6.25.1", 142 | "@types/istanbul-lib-coverage": "1.1.0", 143 | "@types/source-map": "0.1.29" 144 | } 145 | }, 146 | "@types/istanbul-lib-report": { 147 | "version": "1.1.0", 148 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.0.tgz", 149 | "integrity": "sha512-nW5QuzmMhr7fHPijtaGOemFFI8Ctrxb/dIXgouSlKmWT16RxWlGLEX/nGghIBOReKe9hPFZXoNh338nFQk2xcA==", 150 | "requires": { 151 | "@types/istanbul-lib-coverage": "1.1.0" 152 | } 153 | }, 154 | "@types/istanbul-lib-source-maps": { 155 | "version": "1.2.0", 156 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.0.tgz", 157 | "integrity": "sha512-GxjyOSIZC/HETEo61MOjM72qdZH0F9UwfuXCKhmgqhVC7PSjE61BU2I/2eZwQ43+kSdkxKvnOBqqNZi1HHHNEA==", 158 | "requires": { 159 | "@types/istanbul-lib-coverage": "1.1.0", 160 | "@types/source-map": "0.1.29" 161 | } 162 | }, 163 | "@types/istanbul-reports": { 164 | "version": "1.1.0", 165 | "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.0.tgz", 166 | "integrity": "sha512-wrJUtE1+HuaRz0Le7fc5l1nMTermRh6wlEvOdQPilseNScyYgQK8MdgDP2cf/X8+6e1dtsX/zP4W4kH/jyHvFw==", 167 | "requires": { 168 | "@types/istanbul-lib-coverage": "1.1.0", 169 | "@types/istanbul-lib-report": "1.1.0" 170 | } 171 | }, 172 | "@types/jszip": { 173 | "version": "0.0.33", 174 | "resolved": "https://registry.npmjs.org/@types/jszip/-/jszip-0.0.33.tgz", 175 | "integrity": "sha512-zAbqAUQmXP9/ryVysJO6XkogdIdtVIYYGmV7BzhKuagaS+75QZ6muJjeSaG5M8rdE5jQ8gyhkZ23r6l4ICmxyQ==" 176 | }, 177 | "@types/lodash": { 178 | "version": "4.14.85", 179 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.85.tgz", 180 | "integrity": "sha512-HrZiwDl62if0z31+rB99CLlg7WzS7b+KmyW75XAHEl/ZG0De2ACo6skZ89Zh3jOWkjKObN0Apq3MUezg7u9NKQ==" 181 | }, 182 | "@types/mime": { 183 | "version": "2.0.0", 184 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", 185 | "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" 186 | }, 187 | "@types/mime-types": { 188 | "version": "2.1.0", 189 | "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz", 190 | "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=" 191 | }, 192 | "@types/node": { 193 | "version": "8.0.53", 194 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz", 195 | "integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ==" 196 | }, 197 | "@types/platform": { 198 | "version": "1.3.1", 199 | "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.1.tgz", 200 | "integrity": "sha512-XI6JKLFNBmkADRd2FtUYtEuq5LDKTNXwUIodV3ZfTNkA+g4yo+rXXXdZL3fTE24S92BjpiEVaL3f64Fxm2JOgg==" 201 | }, 202 | "@types/resolve": { 203 | "version": "0.0.4", 204 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.4.tgz", 205 | "integrity": "sha1-m1htZalH3qiMS8JNoLkF/pUgoNU=", 206 | "requires": { 207 | "@types/node": "8.0.53" 208 | } 209 | }, 210 | "@types/serve-static": { 211 | "version": "1.13.1", 212 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz", 213 | "integrity": "sha512-jDMH+3BQPtvqZVIcsH700Dfi8Q3MIcEx16g/VdxjoqiGR/NntekB10xdBpirMKnPe9z2C5cBmL0vte0YttOr3Q==", 214 | "requires": { 215 | "@types/express-serve-static-core": "4.0.57", 216 | "@types/mime": "2.0.0" 217 | } 218 | }, 219 | "@types/shell-quote": { 220 | "version": "1.6.0", 221 | "resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.6.0.tgz", 222 | "integrity": "sha512-BFonQx849sYB2YOJZBUEfbWdaJcqRb6+ASvgUBtcmg2JRTjBaV2Wgn0SD0gWNIZ+rd7KPysPCjLUOUXnBDUlBg==" 223 | }, 224 | "@types/source-map": { 225 | "version": "0.1.29", 226 | "resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.1.29.tgz", 227 | "integrity": "sha1-1wSKYBgLCfiqbVO9oxHGtRy9cBg=" 228 | }, 229 | "@types/statuses": { 230 | "version": "1.2.28", 231 | "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-1.2.28.tgz", 232 | "integrity": "sha1-zF8Z0haUFtVWzcoFtZsp5F+kl+I=" 233 | }, 234 | "@types/ws": { 235 | "version": "0.0.42", 236 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-0.0.42.tgz", 237 | "integrity": "sha512-+30f9gcx24GZRD9EqqiQM+I5pRf/MJiJoEqp2X62QRwfEjdqyn9mPmjxZAEXBUVunWotE5qkadIPqf2MMcDYNw==", 238 | "requires": { 239 | "@types/node": "8.0.53" 240 | } 241 | }, 242 | "accepts": { 243 | "version": "1.3.4", 244 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", 245 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", 246 | "requires": { 247 | "mime-types": "2.1.17", 248 | "negotiator": "0.6.1" 249 | } 250 | }, 251 | "align-text": { 252 | "version": "0.1.4", 253 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 254 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 255 | "requires": { 256 | "kind-of": "3.2.2", 257 | "longest": "1.0.1", 258 | "repeat-string": "1.6.1" 259 | } 260 | }, 261 | "amdefine": { 262 | "version": "1.0.1", 263 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 264 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" 265 | }, 266 | "ansi-regex": { 267 | "version": "2.1.1", 268 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 269 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 270 | }, 271 | "ansi-styles": { 272 | "version": "2.2.1", 273 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 274 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" 275 | }, 276 | "append-transform": { 277 | "version": "0.4.0", 278 | "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", 279 | "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", 280 | "requires": { 281 | "default-require-extensions": "1.0.0" 282 | } 283 | }, 284 | "array-filter": { 285 | "version": "0.0.1", 286 | "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", 287 | "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" 288 | }, 289 | "array-flatten": { 290 | "version": "1.1.1", 291 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 292 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 293 | }, 294 | "array-map": { 295 | "version": "0.0.0", 296 | "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", 297 | "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" 298 | }, 299 | "array-reduce": { 300 | "version": "0.0.0", 301 | "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", 302 | "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" 303 | }, 304 | "assertion-error": { 305 | "version": "1.0.2", 306 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", 307 | "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" 308 | }, 309 | "async": { 310 | "version": "1.5.2", 311 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 312 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" 313 | }, 314 | "babel-code-frame": { 315 | "version": "6.26.0", 316 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 317 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 318 | "requires": { 319 | "chalk": "1.1.3", 320 | "esutils": "2.0.2", 321 | "js-tokens": "3.0.2" 322 | } 323 | }, 324 | "babel-generator": { 325 | "version": "6.26.0", 326 | "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", 327 | "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", 328 | "requires": { 329 | "babel-messages": "6.23.0", 330 | "babel-runtime": "6.26.0", 331 | "babel-types": "6.26.0", 332 | "detect-indent": "4.0.0", 333 | "jsesc": "1.3.0", 334 | "lodash": "4.17.4", 335 | "source-map": "0.5.7", 336 | "trim-right": "1.0.1" 337 | } 338 | }, 339 | "babel-messages": { 340 | "version": "6.23.0", 341 | "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", 342 | "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", 343 | "requires": { 344 | "babel-runtime": "6.26.0" 345 | } 346 | }, 347 | "babel-runtime": { 348 | "version": "6.26.0", 349 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", 350 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", 351 | "requires": { 352 | "core-js": "2.5.1", 353 | "regenerator-runtime": "0.11.0" 354 | }, 355 | "dependencies": { 356 | "core-js": { 357 | "version": "2.5.1", 358 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", 359 | "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" 360 | } 361 | } 362 | }, 363 | "babel-template": { 364 | "version": "6.26.0", 365 | "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", 366 | "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", 367 | "requires": { 368 | "babel-runtime": "6.26.0", 369 | "babel-traverse": "6.26.0", 370 | "babel-types": "6.26.0", 371 | "babylon": "6.18.0", 372 | "lodash": "4.17.4" 373 | } 374 | }, 375 | "babel-traverse": { 376 | "version": "6.26.0", 377 | "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", 378 | "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", 379 | "requires": { 380 | "babel-code-frame": "6.26.0", 381 | "babel-messages": "6.23.0", 382 | "babel-runtime": "6.26.0", 383 | "babel-types": "6.26.0", 384 | "babylon": "6.18.0", 385 | "debug": "2.6.9", 386 | "globals": "9.18.0", 387 | "invariant": "2.2.2", 388 | "lodash": "4.17.4" 389 | }, 390 | "dependencies": { 391 | "debug": { 392 | "version": "2.6.9", 393 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 394 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 395 | "requires": { 396 | "ms": "2.0.0" 397 | } 398 | } 399 | } 400 | }, 401 | "babel-types": { 402 | "version": "6.26.0", 403 | "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", 404 | "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", 405 | "requires": { 406 | "babel-runtime": "6.26.0", 407 | "esutils": "2.0.2", 408 | "lodash": "4.17.4", 409 | "to-fast-properties": "1.0.3" 410 | } 411 | }, 412 | "babylon": { 413 | "version": "6.18.0", 414 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", 415 | "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" 416 | }, 417 | "balanced-match": { 418 | "version": "1.0.0", 419 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 420 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 421 | }, 422 | "base64-js": { 423 | "version": "0.0.8", 424 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", 425 | "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=" 426 | }, 427 | "benchmark": { 428 | "version": "2.1.4", 429 | "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", 430 | "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", 431 | "requires": { 432 | "lodash": "4.17.4", 433 | "platform": "1.3.4" 434 | } 435 | }, 436 | "bl": { 437 | "version": "1.2.1", 438 | "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", 439 | "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", 440 | "requires": { 441 | "readable-stream": "2.3.3" 442 | } 443 | }, 444 | "body-parser": { 445 | "version": "1.17.2", 446 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", 447 | "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", 448 | "requires": { 449 | "bytes": "2.4.0", 450 | "content-type": "1.0.4", 451 | "debug": "2.6.7", 452 | "depd": "1.1.1", 453 | "http-errors": "1.6.2", 454 | "iconv-lite": "0.4.15", 455 | "on-finished": "2.3.0", 456 | "qs": "6.4.0", 457 | "raw-body": "2.2.0", 458 | "type-is": "1.6.15" 459 | } 460 | }, 461 | "brace-expansion": { 462 | "version": "1.1.8", 463 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 464 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 465 | "requires": { 466 | "balanced-match": "1.0.0", 467 | "concat-map": "0.0.1" 468 | } 469 | }, 470 | "buffer": { 471 | "version": "3.6.0", 472 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", 473 | "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", 474 | "requires": { 475 | "base64-js": "0.0.8", 476 | "ieee754": "1.1.8", 477 | "isarray": "1.0.0" 478 | } 479 | }, 480 | "buffer-crc32": { 481 | "version": "0.2.13", 482 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 483 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" 484 | }, 485 | "bytes": { 486 | "version": "2.4.0", 487 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", 488 | "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" 489 | }, 490 | "camelcase": { 491 | "version": "1.2.1", 492 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 493 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 494 | "optional": true 495 | }, 496 | "center-align": { 497 | "version": "0.1.3", 498 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 499 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 500 | "optional": true, 501 | "requires": { 502 | "align-text": "0.1.4", 503 | "lazy-cache": "1.0.4" 504 | } 505 | }, 506 | "chai": { 507 | "version": "4.1.2", 508 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", 509 | "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", 510 | "requires": { 511 | "assertion-error": "1.0.2", 512 | "check-error": "1.0.2", 513 | "deep-eql": "3.0.1", 514 | "get-func-name": "2.0.0", 515 | "pathval": "1.1.0", 516 | "type-detect": "4.0.5" 517 | } 518 | }, 519 | "chalk": { 520 | "version": "1.1.3", 521 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 522 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 523 | "requires": { 524 | "ansi-styles": "2.2.1", 525 | "escape-string-regexp": "1.0.5", 526 | "has-ansi": "2.0.0", 527 | "strip-ansi": "3.0.1", 528 | "supports-color": "2.0.0" 529 | } 530 | }, 531 | "charm": { 532 | "version": "1.0.2", 533 | "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", 534 | "integrity": "sha1-it02cVOm2aWBMxBSxAkJkdqZXjU=", 535 | "requires": { 536 | "inherits": "2.0.3" 537 | } 538 | }, 539 | "check-error": { 540 | "version": "1.0.2", 541 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 542 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" 543 | }, 544 | "cliui": { 545 | "version": "2.1.0", 546 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 547 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 548 | "optional": true, 549 | "requires": { 550 | "center-align": "0.1.3", 551 | "right-align": "0.1.3", 552 | "wordwrap": "0.0.2" 553 | }, 554 | "dependencies": { 555 | "wordwrap": { 556 | "version": "0.0.2", 557 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 558 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 559 | "optional": true 560 | } 561 | } 562 | }, 563 | "commander": { 564 | "version": "2.8.1", 565 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", 566 | "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", 567 | "requires": { 568 | "graceful-readlink": "1.0.1" 569 | } 570 | }, 571 | "concat-map": { 572 | "version": "0.0.1", 573 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 574 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 575 | }, 576 | "content-disposition": { 577 | "version": "0.5.2", 578 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 579 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 580 | }, 581 | "content-type": { 582 | "version": "1.0.4", 583 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 584 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 585 | }, 586 | "cookie": { 587 | "version": "0.3.1", 588 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 589 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 590 | }, 591 | "cookie-signature": { 592 | "version": "1.0.6", 593 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 594 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 595 | }, 596 | "core-js": { 597 | "version": "2.3.0", 598 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", 599 | "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=" 600 | }, 601 | "core-util-is": { 602 | "version": "1.0.2", 603 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 604 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 605 | }, 606 | "debug": { 607 | "version": "2.6.7", 608 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", 609 | "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", 610 | "requires": { 611 | "ms": "2.0.0" 612 | } 613 | }, 614 | "decamelize": { 615 | "version": "1.2.0", 616 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 617 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 618 | "optional": true 619 | }, 620 | "decompress": { 621 | "version": "4.2.0", 622 | "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", 623 | "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", 624 | "requires": { 625 | "decompress-tar": "4.1.1", 626 | "decompress-tarbz2": "4.1.1", 627 | "decompress-targz": "4.1.1", 628 | "decompress-unzip": "4.0.1", 629 | "graceful-fs": "4.1.11", 630 | "make-dir": "1.1.0", 631 | "pify": "2.3.0", 632 | "strip-dirs": "2.1.0" 633 | } 634 | }, 635 | "decompress-tar": { 636 | "version": "4.1.1", 637 | "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", 638 | "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", 639 | "requires": { 640 | "file-type": "5.2.0", 641 | "is-stream": "1.1.0", 642 | "tar-stream": "1.5.5" 643 | } 644 | }, 645 | "decompress-tarbz2": { 646 | "version": "4.1.1", 647 | "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", 648 | "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", 649 | "requires": { 650 | "decompress-tar": "4.1.1", 651 | "file-type": "6.2.0", 652 | "is-stream": "1.1.0", 653 | "seek-bzip": "1.0.5", 654 | "unbzip2-stream": "1.2.5" 655 | }, 656 | "dependencies": { 657 | "file-type": { 658 | "version": "6.2.0", 659 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", 660 | "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" 661 | } 662 | } 663 | }, 664 | "decompress-targz": { 665 | "version": "4.1.1", 666 | "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", 667 | "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", 668 | "requires": { 669 | "decompress-tar": "4.1.1", 670 | "file-type": "5.2.0", 671 | "is-stream": "1.1.0" 672 | } 673 | }, 674 | "decompress-unzip": { 675 | "version": "4.0.1", 676 | "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", 677 | "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", 678 | "requires": { 679 | "file-type": "3.9.0", 680 | "get-stream": "2.3.1", 681 | "pify": "2.3.0", 682 | "yauzl": "2.9.1" 683 | }, 684 | "dependencies": { 685 | "file-type": { 686 | "version": "3.9.0", 687 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", 688 | "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" 689 | } 690 | } 691 | }, 692 | "deep-eql": { 693 | "version": "3.0.1", 694 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 695 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 696 | "requires": { 697 | "type-detect": "4.0.5" 698 | } 699 | }, 700 | "default-require-extensions": { 701 | "version": "1.0.0", 702 | "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", 703 | "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", 704 | "requires": { 705 | "strip-bom": "2.0.0" 706 | } 707 | }, 708 | "depd": { 709 | "version": "1.1.1", 710 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 711 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 712 | }, 713 | "destroy": { 714 | "version": "1.0.4", 715 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 716 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 717 | }, 718 | "detect-indent": { 719 | "version": "4.0.0", 720 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", 721 | "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", 722 | "requires": { 723 | "repeating": "2.0.1" 724 | } 725 | }, 726 | "diff": { 727 | "version": "3.2.0", 728 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", 729 | "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=" 730 | }, 731 | "ee-first": { 732 | "version": "1.1.1", 733 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 734 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 735 | }, 736 | "encodeurl": { 737 | "version": "1.0.1", 738 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 739 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" 740 | }, 741 | "end-of-stream": { 742 | "version": "1.4.0", 743 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", 744 | "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", 745 | "requires": { 746 | "once": "1.4.0" 747 | } 748 | }, 749 | "es6-promise": { 750 | "version": "3.0.2", 751 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", 752 | "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" 753 | }, 754 | "escape-html": { 755 | "version": "1.0.3", 756 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 757 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 758 | }, 759 | "escape-string-regexp": { 760 | "version": "1.0.5", 761 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 762 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 763 | }, 764 | "esutils": { 765 | "version": "2.0.2", 766 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 767 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" 768 | }, 769 | "etag": { 770 | "version": "1.8.1", 771 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 772 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 773 | }, 774 | "express": { 775 | "version": "4.15.5", 776 | "resolved": "https://registry.npmjs.org/express/-/express-4.15.5.tgz", 777 | "integrity": "sha1-ZwI1ypWYiQpa6BcLg9tyK4Qu2Sc=", 778 | "requires": { 779 | "accepts": "1.3.4", 780 | "array-flatten": "1.1.1", 781 | "content-disposition": "0.5.2", 782 | "content-type": "1.0.4", 783 | "cookie": "0.3.1", 784 | "cookie-signature": "1.0.6", 785 | "debug": "2.6.9", 786 | "depd": "1.1.1", 787 | "encodeurl": "1.0.1", 788 | "escape-html": "1.0.3", 789 | "etag": "1.8.1", 790 | "finalhandler": "1.0.6", 791 | "fresh": "0.5.2", 792 | "merge-descriptors": "1.0.1", 793 | "methods": "1.1.2", 794 | "on-finished": "2.3.0", 795 | "parseurl": "1.3.2", 796 | "path-to-regexp": "0.1.7", 797 | "proxy-addr": "1.1.5", 798 | "qs": "6.5.0", 799 | "range-parser": "1.2.0", 800 | "send": "0.15.6", 801 | "serve-static": "1.12.6", 802 | "setprototypeof": "1.0.3", 803 | "statuses": "1.3.1", 804 | "type-is": "1.6.15", 805 | "utils-merge": "1.0.0", 806 | "vary": "1.1.2" 807 | }, 808 | "dependencies": { 809 | "debug": { 810 | "version": "2.6.9", 811 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 812 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 813 | "requires": { 814 | "ms": "2.0.0" 815 | } 816 | }, 817 | "qs": { 818 | "version": "6.5.0", 819 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", 820 | "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==" 821 | } 822 | } 823 | }, 824 | "fd-slicer": { 825 | "version": "1.0.1", 826 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", 827 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", 828 | "requires": { 829 | "pend": "1.2.0" 830 | } 831 | }, 832 | "file-type": { 833 | "version": "5.2.0", 834 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", 835 | "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" 836 | }, 837 | "finalhandler": { 838 | "version": "1.0.6", 839 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz", 840 | "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=", 841 | "requires": { 842 | "debug": "2.6.9", 843 | "encodeurl": "1.0.1", 844 | "escape-html": "1.0.3", 845 | "on-finished": "2.3.0", 846 | "parseurl": "1.3.2", 847 | "statuses": "1.3.1", 848 | "unpipe": "1.0.0" 849 | }, 850 | "dependencies": { 851 | "debug": { 852 | "version": "2.6.9", 853 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 854 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 855 | "requires": { 856 | "ms": "2.0.0" 857 | } 858 | } 859 | } 860 | }, 861 | "forwarded": { 862 | "version": "0.1.2", 863 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 864 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 865 | }, 866 | "fresh": { 867 | "version": "0.5.2", 868 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 869 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 870 | }, 871 | "fs.realpath": { 872 | "version": "1.0.0", 873 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 874 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 875 | }, 876 | "get-func-name": { 877 | "version": "2.0.0", 878 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 879 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" 880 | }, 881 | "get-stream": { 882 | "version": "2.3.1", 883 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", 884 | "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", 885 | "requires": { 886 | "object-assign": "4.1.1", 887 | "pinkie-promise": "2.0.1" 888 | } 889 | }, 890 | "glob": { 891 | "version": "7.1.2", 892 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 893 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 894 | "requires": { 895 | "fs.realpath": "1.0.0", 896 | "inflight": "1.0.6", 897 | "inherits": "2.0.3", 898 | "minimatch": "3.0.4", 899 | "once": "1.4.0", 900 | "path-is-absolute": "1.0.1" 901 | } 902 | }, 903 | "globals": { 904 | "version": "9.18.0", 905 | "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", 906 | "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" 907 | }, 908 | "graceful-fs": { 909 | "version": "4.1.11", 910 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 911 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 912 | }, 913 | "graceful-readlink": { 914 | "version": "1.0.1", 915 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", 916 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" 917 | }, 918 | "handlebars": { 919 | "version": "4.0.11", 920 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", 921 | "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", 922 | "requires": { 923 | "async": "1.5.2", 924 | "optimist": "0.6.1", 925 | "source-map": "0.4.4", 926 | "uglify-js": "2.8.29" 927 | }, 928 | "dependencies": { 929 | "source-map": { 930 | "version": "0.4.4", 931 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", 932 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", 933 | "requires": { 934 | "amdefine": "1.0.1" 935 | } 936 | } 937 | } 938 | }, 939 | "has-ansi": { 940 | "version": "2.0.0", 941 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 942 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 943 | "requires": { 944 | "ansi-regex": "2.1.1" 945 | } 946 | }, 947 | "has-flag": { 948 | "version": "1.0.0", 949 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", 950 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" 951 | }, 952 | "http-errors": { 953 | "version": "1.6.2", 954 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 955 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 956 | "requires": { 957 | "depd": "1.1.1", 958 | "inherits": "2.0.3", 959 | "setprototypeof": "1.0.3", 960 | "statuses": "1.3.1" 961 | } 962 | }, 963 | "iconv-lite": { 964 | "version": "0.4.15", 965 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", 966 | "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" 967 | }, 968 | "ieee754": { 969 | "version": "1.1.8", 970 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", 971 | "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" 972 | }, 973 | "immediate": { 974 | "version": "3.0.6", 975 | "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", 976 | "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" 977 | }, 978 | "inflight": { 979 | "version": "1.0.6", 980 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 981 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 982 | "requires": { 983 | "once": "1.4.0", 984 | "wrappy": "1.0.2" 985 | } 986 | }, 987 | "inherits": { 988 | "version": "2.0.3", 989 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 990 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 991 | }, 992 | "intern": { 993 | "version": "4.1.2", 994 | "resolved": "https://registry.npmjs.org/intern/-/intern-4.1.2.tgz", 995 | "integrity": "sha512-R4hJ+PUkp733rVtq5ndIlVmYS5JDLjueYR0vJq1OHwOFoQv2fMcIZMdNGyZh2KbNa4PlTeZOA4934tF7Tkc/IQ==", 996 | "requires": { 997 | "@dojo/core": "0.1.0", 998 | "@dojo/has": "0.1.0", 999 | "@dojo/interfaces": "0.1.0", 1000 | "@dojo/shim": "0.1.0", 1001 | "@theintern/digdug": "2.0.3", 1002 | "@theintern/leadfoot": "2.0.2", 1003 | "@types/benchmark": "1.0.31", 1004 | "@types/chai": "4.0.5", 1005 | "@types/charm": "1.0.1", 1006 | "@types/diff": "3.2.2", 1007 | "@types/express": "4.0.39", 1008 | "@types/http-errors": "1.5.34", 1009 | "@types/istanbul-lib-coverage": "1.1.0", 1010 | "@types/istanbul-lib-hook": "1.0.0", 1011 | "@types/istanbul-lib-instrument": "1.7.0", 1012 | "@types/istanbul-lib-report": "1.1.0", 1013 | "@types/istanbul-lib-source-maps": "1.2.0", 1014 | "@types/istanbul-reports": "1.1.0", 1015 | "@types/lodash": "4.14.85", 1016 | "@types/mime-types": "2.1.0", 1017 | "@types/platform": "1.3.1", 1018 | "@types/resolve": "0.0.4", 1019 | "@types/shell-quote": "1.6.0", 1020 | "@types/source-map": "0.1.29", 1021 | "@types/statuses": "1.2.28", 1022 | "@types/ws": "0.0.42", 1023 | "benchmark": "2.1.4", 1024 | "body-parser": "1.17.2", 1025 | "chai": "4.1.2", 1026 | "charm": "1.0.2", 1027 | "diff": "3.2.0", 1028 | "express": "4.15.5", 1029 | "glob": "7.1.2", 1030 | "http-errors": "1.6.2", 1031 | "istanbul-lib-coverage": "1.1.1", 1032 | "istanbul-lib-hook": "1.0.7", 1033 | "istanbul-lib-instrument": "1.7.5", 1034 | "istanbul-lib-report": "1.1.2", 1035 | "istanbul-lib-source-maps": "1.2.2", 1036 | "istanbul-reports": "1.1.3", 1037 | "lodash": "4.17.4", 1038 | "mime-types": "2.1.17", 1039 | "minimatch": "3.0.4", 1040 | "platform": "1.3.4", 1041 | "resolve": "1.4.0", 1042 | "shell-quote": "1.6.1", 1043 | "source-map": "0.5.7", 1044 | "statuses": "1.3.1", 1045 | "tslib": "1.8.0", 1046 | "ws": "2.3.1" 1047 | } 1048 | }, 1049 | "invariant": { 1050 | "version": "2.2.2", 1051 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", 1052 | "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", 1053 | "requires": { 1054 | "loose-envify": "1.3.1" 1055 | } 1056 | }, 1057 | "ipaddr.js": { 1058 | "version": "1.4.0", 1059 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", 1060 | "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=" 1061 | }, 1062 | "is-buffer": { 1063 | "version": "1.1.6", 1064 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1065 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1066 | }, 1067 | "is-finite": { 1068 | "version": "1.0.2", 1069 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 1070 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 1071 | "requires": { 1072 | "number-is-nan": "1.0.1" 1073 | } 1074 | }, 1075 | "is-natural-number": { 1076 | "version": "4.0.1", 1077 | "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", 1078 | "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" 1079 | }, 1080 | "is-stream": { 1081 | "version": "1.1.0", 1082 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 1083 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 1084 | }, 1085 | "is-utf8": { 1086 | "version": "0.2.1", 1087 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 1088 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" 1089 | }, 1090 | "isarray": { 1091 | "version": "1.0.0", 1092 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1093 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 1094 | }, 1095 | "istanbul-lib-coverage": { 1096 | "version": "1.1.1", 1097 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", 1098 | "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==" 1099 | }, 1100 | "istanbul-lib-hook": { 1101 | "version": "1.0.7", 1102 | "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", 1103 | "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", 1104 | "requires": { 1105 | "append-transform": "0.4.0" 1106 | } 1107 | }, 1108 | "istanbul-lib-instrument": { 1109 | "version": "1.7.5", 1110 | "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.5.tgz", 1111 | "integrity": "sha1-rbWW+PDLi5XnOSBjUaOKWGryGx4=", 1112 | "requires": { 1113 | "babel-generator": "6.26.0", 1114 | "babel-template": "6.26.0", 1115 | "babel-traverse": "6.26.0", 1116 | "babel-types": "6.26.0", 1117 | "babylon": "6.18.0", 1118 | "istanbul-lib-coverage": "1.1.1", 1119 | "semver": "5.4.1" 1120 | } 1121 | }, 1122 | "istanbul-lib-report": { 1123 | "version": "1.1.2", 1124 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz", 1125 | "integrity": "sha512-UTv4VGx+HZivJQwAo1wnRwe1KTvFpfi/NYwN7DcsrdzMXwpRT/Yb6r4SBPoHWj4VuQPakR32g4PUUeyKkdDkBA==", 1126 | "requires": { 1127 | "istanbul-lib-coverage": "1.1.1", 1128 | "mkdirp": "0.5.1", 1129 | "path-parse": "1.0.5", 1130 | "supports-color": "3.2.3" 1131 | }, 1132 | "dependencies": { 1133 | "supports-color": { 1134 | "version": "3.2.3", 1135 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", 1136 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 1137 | "requires": { 1138 | "has-flag": "1.0.0" 1139 | } 1140 | } 1141 | } 1142 | }, 1143 | "istanbul-lib-source-maps": { 1144 | "version": "1.2.2", 1145 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz", 1146 | "integrity": "sha512-8BfdqSfEdtip7/wo1RnrvLpHVEd8zMZEDmOFEnpC6dg0vXflHt9nvoAyQUzig2uMSXfF2OBEYBV3CVjIL9JvaQ==", 1147 | "requires": { 1148 | "debug": "3.1.0", 1149 | "istanbul-lib-coverage": "1.1.1", 1150 | "mkdirp": "0.5.1", 1151 | "rimraf": "2.6.2", 1152 | "source-map": "0.5.7" 1153 | }, 1154 | "dependencies": { 1155 | "debug": { 1156 | "version": "3.1.0", 1157 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1158 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1159 | "requires": { 1160 | "ms": "2.0.0" 1161 | } 1162 | } 1163 | } 1164 | }, 1165 | "istanbul-reports": { 1166 | "version": "1.1.3", 1167 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.3.tgz", 1168 | "integrity": "sha512-ZEelkHh8hrZNI5xDaKwPMFwDsUf5wIEI2bXAFGp1e6deR2mnEKBPhLJEgr4ZBt8Gi6Mj38E/C8kcy9XLggVO2Q==", 1169 | "requires": { 1170 | "handlebars": "4.0.11" 1171 | } 1172 | }, 1173 | "js-tokens": { 1174 | "version": "3.0.2", 1175 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1176 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" 1177 | }, 1178 | "jsesc": { 1179 | "version": "1.3.0", 1180 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", 1181 | "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" 1182 | }, 1183 | "jsonify": { 1184 | "version": "0.0.0", 1185 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", 1186 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" 1187 | }, 1188 | "jszip": { 1189 | "version": "3.1.5", 1190 | "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", 1191 | "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", 1192 | "requires": { 1193 | "core-js": "2.3.0", 1194 | "es6-promise": "3.0.2", 1195 | "lie": "3.1.1", 1196 | "pako": "1.0.6", 1197 | "readable-stream": "2.0.6" 1198 | }, 1199 | "dependencies": { 1200 | "readable-stream": { 1201 | "version": "2.0.6", 1202 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", 1203 | "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", 1204 | "requires": { 1205 | "core-util-is": "1.0.2", 1206 | "inherits": "2.0.3", 1207 | "isarray": "1.0.0", 1208 | "process-nextick-args": "1.0.7", 1209 | "string_decoder": "0.10.31", 1210 | "util-deprecate": "1.0.2" 1211 | } 1212 | }, 1213 | "string_decoder": { 1214 | "version": "0.10.31", 1215 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1216 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 1217 | } 1218 | } 1219 | }, 1220 | "kind-of": { 1221 | "version": "3.2.2", 1222 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1223 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1224 | "requires": { 1225 | "is-buffer": "1.1.6" 1226 | } 1227 | }, 1228 | "lazy-cache": { 1229 | "version": "1.0.4", 1230 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 1231 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 1232 | "optional": true 1233 | }, 1234 | "lie": { 1235 | "version": "3.1.1", 1236 | "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", 1237 | "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", 1238 | "requires": { 1239 | "immediate": "3.0.6" 1240 | } 1241 | }, 1242 | "lodash": { 1243 | "version": "4.17.4", 1244 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 1245 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 1246 | }, 1247 | "longest": { 1248 | "version": "1.0.1", 1249 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 1250 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" 1251 | }, 1252 | "loose-envify": { 1253 | "version": "1.3.1", 1254 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 1255 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 1256 | "requires": { 1257 | "js-tokens": "3.0.2" 1258 | } 1259 | }, 1260 | "make-dir": { 1261 | "version": "1.1.0", 1262 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", 1263 | "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", 1264 | "requires": { 1265 | "pify": "3.0.0" 1266 | }, 1267 | "dependencies": { 1268 | "pify": { 1269 | "version": "3.0.0", 1270 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 1271 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 1272 | } 1273 | } 1274 | }, 1275 | "media-typer": { 1276 | "version": "0.3.0", 1277 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1278 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1279 | }, 1280 | "merge-descriptors": { 1281 | "version": "1.0.1", 1282 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1283 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 1284 | }, 1285 | "methods": { 1286 | "version": "1.1.2", 1287 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1288 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1289 | }, 1290 | "mime": { 1291 | "version": "1.3.4", 1292 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", 1293 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" 1294 | }, 1295 | "mime-db": { 1296 | "version": "1.30.0", 1297 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", 1298 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" 1299 | }, 1300 | "mime-types": { 1301 | "version": "2.1.17", 1302 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", 1303 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", 1304 | "requires": { 1305 | "mime-db": "1.30.0" 1306 | } 1307 | }, 1308 | "minimatch": { 1309 | "version": "3.0.4", 1310 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1311 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1312 | "requires": { 1313 | "brace-expansion": "1.1.8" 1314 | } 1315 | }, 1316 | "minimist": { 1317 | "version": "0.0.8", 1318 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1319 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 1320 | }, 1321 | "mkdirp": { 1322 | "version": "0.5.1", 1323 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1324 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1325 | "requires": { 1326 | "minimist": "0.0.8" 1327 | } 1328 | }, 1329 | "ms": { 1330 | "version": "2.0.0", 1331 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1332 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1333 | }, 1334 | "negotiator": { 1335 | "version": "0.6.1", 1336 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 1337 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 1338 | }, 1339 | "number-is-nan": { 1340 | "version": "1.0.1", 1341 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 1342 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 1343 | }, 1344 | "object-assign": { 1345 | "version": "4.1.1", 1346 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1347 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1348 | }, 1349 | "on-finished": { 1350 | "version": "2.3.0", 1351 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1352 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1353 | "requires": { 1354 | "ee-first": "1.1.1" 1355 | } 1356 | }, 1357 | "once": { 1358 | "version": "1.4.0", 1359 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1360 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1361 | "requires": { 1362 | "wrappy": "1.0.2" 1363 | } 1364 | }, 1365 | "optimist": { 1366 | "version": "0.6.1", 1367 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 1368 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 1369 | "requires": { 1370 | "minimist": "0.0.8", 1371 | "wordwrap": "0.0.3" 1372 | } 1373 | }, 1374 | "pako": { 1375 | "version": "1.0.6", 1376 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", 1377 | "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" 1378 | }, 1379 | "parseurl": { 1380 | "version": "1.3.2", 1381 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 1382 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 1383 | }, 1384 | "path-is-absolute": { 1385 | "version": "1.0.1", 1386 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1387 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1388 | }, 1389 | "path-parse": { 1390 | "version": "1.0.5", 1391 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 1392 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" 1393 | }, 1394 | "path-to-regexp": { 1395 | "version": "0.1.7", 1396 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1397 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1398 | }, 1399 | "pathval": { 1400 | "version": "1.1.0", 1401 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 1402 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" 1403 | }, 1404 | "pend": { 1405 | "version": "1.2.0", 1406 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 1407 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 1408 | }, 1409 | "pify": { 1410 | "version": "2.3.0", 1411 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1412 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" 1413 | }, 1414 | "pinkie": { 1415 | "version": "2.0.4", 1416 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1417 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" 1418 | }, 1419 | "pinkie-promise": { 1420 | "version": "2.0.1", 1421 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1422 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1423 | "requires": { 1424 | "pinkie": "2.0.4" 1425 | } 1426 | }, 1427 | "platform": { 1428 | "version": "1.3.4", 1429 | "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz", 1430 | "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=" 1431 | }, 1432 | "process-nextick-args": { 1433 | "version": "1.0.7", 1434 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 1435 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" 1436 | }, 1437 | "proxy-addr": { 1438 | "version": "1.1.5", 1439 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", 1440 | "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", 1441 | "requires": { 1442 | "forwarded": "0.1.2", 1443 | "ipaddr.js": "1.4.0" 1444 | } 1445 | }, 1446 | "qs": { 1447 | "version": "6.4.0", 1448 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", 1449 | "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" 1450 | }, 1451 | "range-parser": { 1452 | "version": "1.2.0", 1453 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 1454 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 1455 | }, 1456 | "raw-body": { 1457 | "version": "2.2.0", 1458 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", 1459 | "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", 1460 | "requires": { 1461 | "bytes": "2.4.0", 1462 | "iconv-lite": "0.4.15", 1463 | "unpipe": "1.0.0" 1464 | } 1465 | }, 1466 | "readable-stream": { 1467 | "version": "2.3.3", 1468 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 1469 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 1470 | "requires": { 1471 | "core-util-is": "1.0.2", 1472 | "inherits": "2.0.3", 1473 | "isarray": "1.0.0", 1474 | "process-nextick-args": "1.0.7", 1475 | "safe-buffer": "5.1.1", 1476 | "string_decoder": "1.0.3", 1477 | "util-deprecate": "1.0.2" 1478 | } 1479 | }, 1480 | "regenerator-runtime": { 1481 | "version": "0.11.0", 1482 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", 1483 | "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" 1484 | }, 1485 | "repeat-string": { 1486 | "version": "1.6.1", 1487 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 1488 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" 1489 | }, 1490 | "repeating": { 1491 | "version": "2.0.1", 1492 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 1493 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 1494 | "requires": { 1495 | "is-finite": "1.0.2" 1496 | } 1497 | }, 1498 | "resolve": { 1499 | "version": "1.4.0", 1500 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", 1501 | "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", 1502 | "requires": { 1503 | "path-parse": "1.0.5" 1504 | } 1505 | }, 1506 | "right-align": { 1507 | "version": "0.1.3", 1508 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 1509 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 1510 | "optional": true, 1511 | "requires": { 1512 | "align-text": "0.1.4" 1513 | } 1514 | }, 1515 | "rimraf": { 1516 | "version": "2.6.2", 1517 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 1518 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 1519 | "requires": { 1520 | "glob": "7.1.2" 1521 | } 1522 | }, 1523 | "safe-buffer": { 1524 | "version": "5.1.1", 1525 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 1526 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 1527 | }, 1528 | "seek-bzip": { 1529 | "version": "1.0.5", 1530 | "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", 1531 | "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", 1532 | "requires": { 1533 | "commander": "2.8.1" 1534 | } 1535 | }, 1536 | "semver": { 1537 | "version": "5.4.1", 1538 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", 1539 | "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" 1540 | }, 1541 | "send": { 1542 | "version": "0.15.6", 1543 | "resolved": "https://registry.npmjs.org/send/-/send-0.15.6.tgz", 1544 | "integrity": "sha1-IPI6nJJbdiq4JwX+L52yUqzkfjQ=", 1545 | "requires": { 1546 | "debug": "2.6.9", 1547 | "depd": "1.1.1", 1548 | "destroy": "1.0.4", 1549 | "encodeurl": "1.0.1", 1550 | "escape-html": "1.0.3", 1551 | "etag": "1.8.1", 1552 | "fresh": "0.5.2", 1553 | "http-errors": "1.6.2", 1554 | "mime": "1.3.4", 1555 | "ms": "2.0.0", 1556 | "on-finished": "2.3.0", 1557 | "range-parser": "1.2.0", 1558 | "statuses": "1.3.1" 1559 | }, 1560 | "dependencies": { 1561 | "debug": { 1562 | "version": "2.6.9", 1563 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1564 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1565 | "requires": { 1566 | "ms": "2.0.0" 1567 | } 1568 | } 1569 | } 1570 | }, 1571 | "serve-static": { 1572 | "version": "1.12.6", 1573 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.6.tgz", 1574 | "integrity": "sha1-uXN3P2NEmTTaVOW+ul4x2fQhFXc=", 1575 | "requires": { 1576 | "encodeurl": "1.0.1", 1577 | "escape-html": "1.0.3", 1578 | "parseurl": "1.3.2", 1579 | "send": "0.15.6" 1580 | } 1581 | }, 1582 | "setprototypeof": { 1583 | "version": "1.0.3", 1584 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 1585 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 1586 | }, 1587 | "shell-quote": { 1588 | "version": "1.6.1", 1589 | "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", 1590 | "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", 1591 | "requires": { 1592 | "array-filter": "0.0.1", 1593 | "array-map": "0.0.0", 1594 | "array-reduce": "0.0.0", 1595 | "jsonify": "0.0.0" 1596 | } 1597 | }, 1598 | "source-map": { 1599 | "version": "0.5.7", 1600 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1601 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" 1602 | }, 1603 | "statuses": { 1604 | "version": "1.3.1", 1605 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", 1606 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 1607 | }, 1608 | "string_decoder": { 1609 | "version": "1.0.3", 1610 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 1611 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 1612 | "requires": { 1613 | "safe-buffer": "5.1.1" 1614 | } 1615 | }, 1616 | "strip-ansi": { 1617 | "version": "3.0.1", 1618 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1619 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1620 | "requires": { 1621 | "ansi-regex": "2.1.1" 1622 | } 1623 | }, 1624 | "strip-bom": { 1625 | "version": "2.0.0", 1626 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 1627 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 1628 | "requires": { 1629 | "is-utf8": "0.2.1" 1630 | } 1631 | }, 1632 | "strip-dirs": { 1633 | "version": "2.1.0", 1634 | "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", 1635 | "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", 1636 | "requires": { 1637 | "is-natural-number": "4.0.1" 1638 | } 1639 | }, 1640 | "supports-color": { 1641 | "version": "2.0.0", 1642 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 1643 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" 1644 | }, 1645 | "tar-stream": { 1646 | "version": "1.5.5", 1647 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", 1648 | "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", 1649 | "requires": { 1650 | "bl": "1.2.1", 1651 | "end-of-stream": "1.4.0", 1652 | "readable-stream": "2.3.3", 1653 | "xtend": "4.0.1" 1654 | } 1655 | }, 1656 | "through": { 1657 | "version": "2.3.8", 1658 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1659 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 1660 | }, 1661 | "to-fast-properties": { 1662 | "version": "1.0.3", 1663 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", 1664 | "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" 1665 | }, 1666 | "trim-right": { 1667 | "version": "1.0.1", 1668 | "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", 1669 | "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" 1670 | }, 1671 | "tslib": { 1672 | "version": "1.8.0", 1673 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", 1674 | "integrity": "sha512-ymKWWZJST0/CkgduC2qkzjMOWr4bouhuURNXCn/inEX0L57BnRG6FhX76o7FOnsjHazCjfU2LKeSrlS2sIKQJg==" 1675 | }, 1676 | "type-detect": { 1677 | "version": "4.0.5", 1678 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", 1679 | "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==" 1680 | }, 1681 | "type-is": { 1682 | "version": "1.6.15", 1683 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", 1684 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", 1685 | "requires": { 1686 | "media-typer": "0.3.0", 1687 | "mime-types": "2.1.17" 1688 | } 1689 | }, 1690 | "uglify-js": { 1691 | "version": "2.8.29", 1692 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 1693 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 1694 | "optional": true, 1695 | "requires": { 1696 | "source-map": "0.5.7", 1697 | "uglify-to-browserify": "1.0.2", 1698 | "yargs": "3.10.0" 1699 | } 1700 | }, 1701 | "uglify-to-browserify": { 1702 | "version": "1.0.2", 1703 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 1704 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 1705 | "optional": true 1706 | }, 1707 | "ultron": { 1708 | "version": "1.1.0", 1709 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.0.tgz", 1710 | "integrity": "sha1-sHoualQagV/Go0zNRTO67DB8qGQ=" 1711 | }, 1712 | "unbzip2-stream": { 1713 | "version": "1.2.5", 1714 | "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", 1715 | "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", 1716 | "requires": { 1717 | "buffer": "3.6.0", 1718 | "through": "2.3.8" 1719 | } 1720 | }, 1721 | "unpipe": { 1722 | "version": "1.0.0", 1723 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1724 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1725 | }, 1726 | "util-deprecate": { 1727 | "version": "1.0.2", 1728 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1729 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1730 | }, 1731 | "utils-merge": { 1732 | "version": "1.0.0", 1733 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", 1734 | "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" 1735 | }, 1736 | "vary": { 1737 | "version": "1.1.2", 1738 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1739 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1740 | }, 1741 | "window-size": { 1742 | "version": "0.1.0", 1743 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 1744 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 1745 | "optional": true 1746 | }, 1747 | "wordwrap": { 1748 | "version": "0.0.3", 1749 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 1750 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" 1751 | }, 1752 | "wrappy": { 1753 | "version": "1.0.2", 1754 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1755 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1756 | }, 1757 | "ws": { 1758 | "version": "2.3.1", 1759 | "resolved": "https://registry.npmjs.org/ws/-/ws-2.3.1.tgz", 1760 | "integrity": "sha1-a5Sz5EfLajY/eF6vlK9jWejoHIA=", 1761 | "requires": { 1762 | "safe-buffer": "5.0.1", 1763 | "ultron": "1.1.0" 1764 | }, 1765 | "dependencies": { 1766 | "safe-buffer": { 1767 | "version": "5.0.1", 1768 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", 1769 | "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" 1770 | } 1771 | } 1772 | }, 1773 | "xtend": { 1774 | "version": "4.0.1", 1775 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 1776 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 1777 | }, 1778 | "yargs": { 1779 | "version": "3.10.0", 1780 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 1781 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 1782 | "optional": true, 1783 | "requires": { 1784 | "camelcase": "1.2.1", 1785 | "cliui": "2.1.0", 1786 | "decamelize": "1.2.0", 1787 | "window-size": "0.1.0" 1788 | } 1789 | }, 1790 | "yauzl": { 1791 | "version": "2.9.1", 1792 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", 1793 | "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", 1794 | "requires": { 1795 | "buffer-crc32": "0.2.13", 1796 | "fd-slicer": "1.0.1" 1797 | } 1798 | } 1799 | } 1800 | } 1801 | -------------------------------------------------------------------------------- /examples/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "intern-a11y-JS-example", 3 | "private": true, 4 | "dependencies": { 5 | "@theintern/a11y": "file:../../_build/src", 6 | "intern": "~4.1.0", 7 | "rimraf": "~2.6.2" 8 | }, 9 | "scripts": { 10 | "test": "intern", 11 | "clean": "rimraf a11y-report" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/js/tests/axe.js: -------------------------------------------------------------------------------- 1 | const { registerSuite } = intern.getInterface('object'); 2 | const { assert } = intern.getPlugin('chai'); 3 | const { join } = require('path'); 4 | const axe = require('@theintern/a11y/services/axe'); 5 | 6 | registerSuite('aXe', { 7 | 'external page'() { 8 | // This test is expected to fail 9 | return this.remote 10 | .get('http://google.com') 11 | .sleep(2000) 12 | .then(axe.createChecker()); 13 | }, 14 | 15 | 'file name'() { 16 | return axe.check({ 17 | remote: this.remote, 18 | source: join(__dirname, 'data/page.html') 19 | }); 20 | }, 21 | 22 | 'bad page'() { 23 | // This test is expected to fail 24 | return axe.check({ 25 | remote: this.remote, 26 | source: join(__dirname, 'data/bad_page.html') 27 | }); 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /examples/js/tests/data/bad_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test page 5 | 6 | 7 | 15 | 16 |
17 |

Testing

18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/js/tests/data/page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test page 5 | 6 | 7 |

Test page

8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/js/tests/tenon.js: -------------------------------------------------------------------------------- 1 | const { registerSuite } = intern.getInterface('object'); 2 | const { assert } = intern.getPlugin('chai'); 3 | const { join } = require('path'); 4 | const tenon = require('@theintern/a11y/services/tenon'); 5 | const keyPresent = process.env['TENON_API_KEY'] != null; 6 | 7 | registerSuite('tenon', { 8 | 'external url'() { 9 | if (!keyPresent) { 10 | this.skip('missing Tenon API key'); 11 | } 12 | return tenon.check({ source: 'http://tenon.io/documentation' }); 13 | }, 14 | 15 | 'file name'() { 16 | if (!keyPresent) { 17 | this.skip('missing Tenon API key'); 18 | } 19 | return tenon.check({ source: join(__dirname, 'data/page.html') }); 20 | }, 21 | 22 | 'bad page'() { 23 | if (!keyPresent) { 24 | this.skip('missing Tenon API key'); 25 | } 26 | return tenon.check({ source: join(__dirname, 'data/bad_page.html') }); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /examples/ts/.gitignore: -------------------------------------------------------------------------------- 1 | tests/*.js 2 | -------------------------------------------------------------------------------- /examples/ts/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript example 2 | 3 | Install: 4 | 5 | ``` 6 | npm install 7 | ``` 8 | 9 | Run tests: 10 | 11 | ``` 12 | TENON_API_KEY= npm test 13 | ``` 14 | 15 | Note that a Tenon API key is required to run tenon tests. If you don't have 16 | one, those tests will be skipped. 17 | 18 | A couple of tests are expected to fail. After tests are run, a report will be 19 | generated in `a11y-report/`. 20 | -------------------------------------------------------------------------------- /examples/ts/intern.json: -------------------------------------------------------------------------------- 1 | { 2 | "environments": [ 3 | "node", 4 | { "browserName": "chrome", "fixSessionCapabilities": "no-detect" } 5 | ], 6 | "functionalSuites": "tests/axe.js", 7 | "node": { 8 | "suites": "tests/tenon.js" 9 | }, 10 | "filterErrorStack": true, 11 | "plugins": "@theintern/a11y/A11yReporter.js" 12 | } 13 | -------------------------------------------------------------------------------- /examples/ts/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "intern-a11y-TS-example", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "@dojo/core": { 7 | "version": "0.1.0", 8 | "resolved": "https://registry.npmjs.org/@dojo/core/-/core-0.1.0.tgz", 9 | "integrity": "sha512-boiwQHfV7idOZfZnDzgLrofS2LA7ELGKjd6tl0/hLBunJ3psozAd4CpNcT7XC00/OPYFIxVHFEpI+FZNlpUgfw==" 10 | }, 11 | "@dojo/has": { 12 | "version": "0.1.0", 13 | "resolved": "https://registry.npmjs.org/@dojo/has/-/has-0.1.0.tgz", 14 | "integrity": "sha512-orYLbYVTcqNpZBmPNRlidUyCn/WuV4jV4JvTAy4Je/zQq9m9Nb8gK+8X7/iOUjSJbP1+vv1ld9Q3932IGC1IyA==" 15 | }, 16 | "@dojo/interfaces": { 17 | "version": "0.1.0", 18 | "resolved": "https://registry.npmjs.org/@dojo/interfaces/-/interfaces-0.1.0.tgz", 19 | "integrity": "sha512-rpBALDc5Ya/+JrlyFvrt7wKGdGA1xq2gSFGce6j3L9meB8tAFYQvs/bx9DDp+CSdpEzzeVZWr8C4FpoUId2New==" 20 | }, 21 | "@dojo/shim": { 22 | "version": "0.1.0", 23 | "resolved": "https://registry.npmjs.org/@dojo/shim/-/shim-0.1.0.tgz", 24 | "integrity": "sha512-008RP8DB175ib26dde7wQWFiYIbSACFaArLdLHYdY/cQLN9s3yVj2Gtp5C/9YoY3Ziy9wA241myOjy6QcVHcWw==" 25 | }, 26 | "@theintern/a11y": { 27 | "version": "file:../../_build/src", 28 | "requires": { 29 | "@types/mkdirp": "0.5.1", 30 | "axe-core": "2.5.0", 31 | "mkdirp": "0.5.1" 32 | }, 33 | "dependencies": { 34 | "@types/mkdirp": { 35 | "version": "0.5.1", 36 | "bundled": true, 37 | "requires": { 38 | "@types/node": "8.0.53" 39 | } 40 | }, 41 | "@types/node": { 42 | "version": "8.0.53", 43 | "bundled": true 44 | }, 45 | "axe-core": { 46 | "version": "2.5.0", 47 | "bundled": true 48 | }, 49 | "minimist": { 50 | "version": "0.0.8", 51 | "bundled": true 52 | }, 53 | "mkdirp": { 54 | "version": "0.5.1", 55 | "bundled": true, 56 | "requires": { 57 | "minimist": "0.0.8" 58 | } 59 | } 60 | } 61 | }, 62 | "@theintern/digdug": { 63 | "version": "2.0.3", 64 | "resolved": "https://registry.npmjs.org/@theintern/digdug/-/digdug-2.0.3.tgz", 65 | "integrity": "sha512-H+XhQeuspFrFgZCn2+rTF0qzmCc6IR2hAW4xCDLUv+20VdMowRQrIwJCYW/nk/YynqKz/p041KNeENajVF5CFg==", 66 | "requires": { 67 | "@dojo/core": "0.1.0", 68 | "@dojo/has": "0.1.0", 69 | "@dojo/interfaces": "0.1.0", 70 | "@dojo/shim": "0.1.0", 71 | "decompress": "4.2.0", 72 | "semver": "5.4.1", 73 | "tslib": "1.8.0" 74 | } 75 | }, 76 | "@theintern/leadfoot": { 77 | "version": "2.0.2", 78 | "resolved": "https://registry.npmjs.org/@theintern/leadfoot/-/leadfoot-2.0.2.tgz", 79 | "integrity": "sha512-WHDp40qrM5BgBHFfeVfdOVVqHV1vCnJeDMobChfD7CYMqW2UHGjsJDgNRW3+xZr/Tek1IsHvfwt+t29iEdNrOg==", 80 | "requires": { 81 | "@dojo/core": "0.1.0", 82 | "@dojo/has": "0.1.0", 83 | "@dojo/interfaces": "0.1.0", 84 | "@dojo/shim": "0.1.0", 85 | "@types/jszip": "0.0.33", 86 | "jszip": "3.1.5", 87 | "tslib": "1.8.0" 88 | } 89 | }, 90 | "@types/babel-types": { 91 | "version": "6.25.1", 92 | "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-6.25.1.tgz", 93 | "integrity": "sha512-7Z6r20+HE0viAFhsW0d/UrC1K2tTlpXzGpNlYm8MmCv8z5PbAacFIshrM/MjlGRa5SBqxu2socpy8FHntwZKng==" 94 | }, 95 | "@types/benchmark": { 96 | "version": "1.0.31", 97 | "resolved": "https://registry.npmjs.org/@types/benchmark/-/benchmark-1.0.31.tgz", 98 | "integrity": "sha512-F6fVNOkGEkSdo/19yWYOwVKGvzbTeWkR/XQYBKtGBQ9oGRjBN9f/L4aJI4sDcVPJO58Y1CJZN8va9V2BhrZapA==" 99 | }, 100 | "@types/body-parser": { 101 | "version": "1.16.8", 102 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.16.8.tgz", 103 | "integrity": "sha512-BdN2PXxOFnTXFcyONPW6t0fHjz2fvRZHVMFpaS0wYr+Y8fWEaNOs4V8LEu/fpzQlMx+ahdndgTaGTwPC+J/EeA==", 104 | "requires": { 105 | "@types/express": "4.0.39", 106 | "@types/node": "8.0.53" 107 | } 108 | }, 109 | "@types/chai": { 110 | "version": "4.0.5", 111 | "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.5.tgz", 112 | "integrity": "sha512-ZC4tZU+3rDblhVy9cUQp5u+Zw9M0geGY8tzUQgc+4CMIWQLUFpgvrHhaYrSq1TK2m0DjaYIp9yJPyTHN+qhBZg==" 113 | }, 114 | "@types/charm": { 115 | "version": "1.0.1", 116 | "resolved": "https://registry.npmjs.org/@types/charm/-/charm-1.0.1.tgz", 117 | "integrity": "sha512-F9OalGhk60p/DnACfa1SWtmVTMni0+w9t/qfb5Bu7CsurkEjZFN7Z+ii/VGmYpaViPz7o3tBahRQae9O7skFlQ==", 118 | "requires": { 119 | "@types/node": "8.0.53" 120 | } 121 | }, 122 | "@types/diff": { 123 | "version": "3.2.2", 124 | "resolved": "https://registry.npmjs.org/@types/diff/-/diff-3.2.2.tgz", 125 | "integrity": "sha512-q3zfJvaTroV5BjAAR+peTHEGAAhGrPX0z2EzCzpt2mwFA+qzUn2nigJLqSekXRtdULKmT8am7zjvTMZSapIgHw==" 126 | }, 127 | "@types/express": { 128 | "version": "4.0.39", 129 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.0.39.tgz", 130 | "integrity": "sha512-dBUam7jEjyuEofigUXCtublUHknRZvcRgITlGsTbFgPvnTwtQUt2NgLakbsf+PsGo/Nupqr3IXCYsOpBpofyrA==", 131 | "requires": { 132 | "@types/body-parser": "1.16.8", 133 | "@types/express-serve-static-core": "4.0.57", 134 | "@types/serve-static": "1.13.1" 135 | } 136 | }, 137 | "@types/express-serve-static-core": { 138 | "version": "4.0.57", 139 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.0.57.tgz", 140 | "integrity": "sha512-QLAHjdLwEICm3thVbXSKRoisjfgMVI4xJH/HU8F385BR2HI7PmM6ax4ELXf8Du6sLmSpySXMYaI+xc//oQ/IFw==", 141 | "requires": { 142 | "@types/node": "8.0.53" 143 | } 144 | }, 145 | "@types/http-errors": { 146 | "version": "1.5.34", 147 | "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-1.5.34.tgz", 148 | "integrity": "sha1-1qVvJde5XdBwR2gL+CVjLil5aBU=" 149 | }, 150 | "@types/istanbul-lib-coverage": { 151 | "version": "1.1.0", 152 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz", 153 | "integrity": "sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ==" 154 | }, 155 | "@types/istanbul-lib-hook": { 156 | "version": "1.0.0", 157 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-hook/-/istanbul-lib-hook-1.0.0.tgz", 158 | "integrity": "sha512-+kdaJ8hO/auIGcqPuSbd3cnTSzgM8ZW0zfYFZLP67vCmWkZV4LdC1XOXpMWnlONup+PChJMK8Q/+Qrh7WoxnUQ==" 159 | }, 160 | "@types/istanbul-lib-instrument": { 161 | "version": "1.7.0", 162 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.0.tgz", 163 | "integrity": "sha512-BWj7zRtwVU5KzuYL/zNuVoSvYWIpT02smNMpQwQbJjwEyITEGSKsxVIT4b2bzXCWFMq76ss0sdY/5yw3NwTlIA==", 164 | "requires": { 165 | "@types/babel-types": "6.25.1", 166 | "@types/istanbul-lib-coverage": "1.1.0", 167 | "@types/source-map": "0.1.29" 168 | } 169 | }, 170 | "@types/istanbul-lib-report": { 171 | "version": "1.1.0", 172 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.0.tgz", 173 | "integrity": "sha512-nW5QuzmMhr7fHPijtaGOemFFI8Ctrxb/dIXgouSlKmWT16RxWlGLEX/nGghIBOReKe9hPFZXoNh338nFQk2xcA==", 174 | "requires": { 175 | "@types/istanbul-lib-coverage": "1.1.0" 176 | } 177 | }, 178 | "@types/istanbul-lib-source-maps": { 179 | "version": "1.2.0", 180 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.0.tgz", 181 | "integrity": "sha512-GxjyOSIZC/HETEo61MOjM72qdZH0F9UwfuXCKhmgqhVC7PSjE61BU2I/2eZwQ43+kSdkxKvnOBqqNZi1HHHNEA==", 182 | "requires": { 183 | "@types/istanbul-lib-coverage": "1.1.0", 184 | "@types/source-map": "0.1.29" 185 | } 186 | }, 187 | "@types/istanbul-reports": { 188 | "version": "1.1.0", 189 | "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.0.tgz", 190 | "integrity": "sha512-wrJUtE1+HuaRz0Le7fc5l1nMTermRh6wlEvOdQPilseNScyYgQK8MdgDP2cf/X8+6e1dtsX/zP4W4kH/jyHvFw==", 191 | "requires": { 192 | "@types/istanbul-lib-coverage": "1.1.0", 193 | "@types/istanbul-lib-report": "1.1.0" 194 | } 195 | }, 196 | "@types/jszip": { 197 | "version": "0.0.33", 198 | "resolved": "https://registry.npmjs.org/@types/jszip/-/jszip-0.0.33.tgz", 199 | "integrity": "sha512-zAbqAUQmXP9/ryVysJO6XkogdIdtVIYYGmV7BzhKuagaS+75QZ6muJjeSaG5M8rdE5jQ8gyhkZ23r6l4ICmxyQ==" 200 | }, 201 | "@types/lodash": { 202 | "version": "4.14.85", 203 | "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.85.tgz", 204 | "integrity": "sha512-HrZiwDl62if0z31+rB99CLlg7WzS7b+KmyW75XAHEl/ZG0De2ACo6skZ89Zh3jOWkjKObN0Apq3MUezg7u9NKQ==" 205 | }, 206 | "@types/mime": { 207 | "version": "2.0.0", 208 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", 209 | "integrity": "sha512-A2TAGbTFdBw9azHbpVd+/FkdW2T6msN1uct1O9bH3vTerEHKZhTXJUQXy+hNq1B0RagfU8U+KBdqiZpxjhOUQA==" 210 | }, 211 | "@types/mime-types": { 212 | "version": "2.1.0", 213 | "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.0.tgz", 214 | "integrity": "sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM=" 215 | }, 216 | "@types/node": { 217 | "version": "8.0.53", 218 | "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.53.tgz", 219 | "integrity": "sha512-54Dm6NwYeiSQmRB1BLXKr5GELi0wFapR1npi8bnZhEcu84d/yQKqnwwXQ56hZ0RUbTG6L5nqDZaN3dgByQXQRQ==" 220 | }, 221 | "@types/platform": { 222 | "version": "1.3.1", 223 | "resolved": "https://registry.npmjs.org/@types/platform/-/platform-1.3.1.tgz", 224 | "integrity": "sha512-XI6JKLFNBmkADRd2FtUYtEuq5LDKTNXwUIodV3ZfTNkA+g4yo+rXXXdZL3fTE24S92BjpiEVaL3f64Fxm2JOgg==" 225 | }, 226 | "@types/resolve": { 227 | "version": "0.0.4", 228 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.4.tgz", 229 | "integrity": "sha1-m1htZalH3qiMS8JNoLkF/pUgoNU=", 230 | "requires": { 231 | "@types/node": "8.0.53" 232 | } 233 | }, 234 | "@types/serve-static": { 235 | "version": "1.13.1", 236 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.1.tgz", 237 | "integrity": "sha512-jDMH+3BQPtvqZVIcsH700Dfi8Q3MIcEx16g/VdxjoqiGR/NntekB10xdBpirMKnPe9z2C5cBmL0vte0YttOr3Q==", 238 | "requires": { 239 | "@types/express-serve-static-core": "4.0.57", 240 | "@types/mime": "2.0.0" 241 | } 242 | }, 243 | "@types/shell-quote": { 244 | "version": "1.6.0", 245 | "resolved": "https://registry.npmjs.org/@types/shell-quote/-/shell-quote-1.6.0.tgz", 246 | "integrity": "sha512-BFonQx849sYB2YOJZBUEfbWdaJcqRb6+ASvgUBtcmg2JRTjBaV2Wgn0SD0gWNIZ+rd7KPysPCjLUOUXnBDUlBg==" 247 | }, 248 | "@types/source-map": { 249 | "version": "0.1.29", 250 | "resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.1.29.tgz", 251 | "integrity": "sha1-1wSKYBgLCfiqbVO9oxHGtRy9cBg=" 252 | }, 253 | "@types/statuses": { 254 | "version": "1.2.28", 255 | "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-1.2.28.tgz", 256 | "integrity": "sha1-zF8Z0haUFtVWzcoFtZsp5F+kl+I=" 257 | }, 258 | "@types/ws": { 259 | "version": "0.0.42", 260 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-0.0.42.tgz", 261 | "integrity": "sha512-+30f9gcx24GZRD9EqqiQM+I5pRf/MJiJoEqp2X62QRwfEjdqyn9mPmjxZAEXBUVunWotE5qkadIPqf2MMcDYNw==", 262 | "requires": { 263 | "@types/node": "8.0.53" 264 | } 265 | }, 266 | "accepts": { 267 | "version": "1.3.4", 268 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", 269 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", 270 | "requires": { 271 | "mime-types": "2.1.17", 272 | "negotiator": "0.6.1" 273 | } 274 | }, 275 | "align-text": { 276 | "version": "0.1.4", 277 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 278 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 279 | "requires": { 280 | "kind-of": "3.2.2", 281 | "longest": "1.0.1", 282 | "repeat-string": "1.6.1" 283 | } 284 | }, 285 | "amdefine": { 286 | "version": "1.0.1", 287 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 288 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" 289 | }, 290 | "ansi-regex": { 291 | "version": "2.1.1", 292 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 293 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 294 | }, 295 | "ansi-styles": { 296 | "version": "2.2.1", 297 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 298 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" 299 | }, 300 | "append-transform": { 301 | "version": "0.4.0", 302 | "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", 303 | "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", 304 | "requires": { 305 | "default-require-extensions": "1.0.0" 306 | } 307 | }, 308 | "array-filter": { 309 | "version": "0.0.1", 310 | "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", 311 | "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" 312 | }, 313 | "array-flatten": { 314 | "version": "1.1.1", 315 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 316 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 317 | }, 318 | "array-map": { 319 | "version": "0.0.0", 320 | "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", 321 | "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" 322 | }, 323 | "array-reduce": { 324 | "version": "0.0.0", 325 | "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", 326 | "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" 327 | }, 328 | "assertion-error": { 329 | "version": "1.0.2", 330 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", 331 | "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" 332 | }, 333 | "async": { 334 | "version": "1.5.2", 335 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 336 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" 337 | }, 338 | "babel-code-frame": { 339 | "version": "6.26.0", 340 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 341 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 342 | "requires": { 343 | "chalk": "1.1.3", 344 | "esutils": "2.0.2", 345 | "js-tokens": "3.0.2" 346 | } 347 | }, 348 | "babel-generator": { 349 | "version": "6.26.0", 350 | "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", 351 | "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", 352 | "requires": { 353 | "babel-messages": "6.23.0", 354 | "babel-runtime": "6.26.0", 355 | "babel-types": "6.26.0", 356 | "detect-indent": "4.0.0", 357 | "jsesc": "1.3.0", 358 | "lodash": "4.17.4", 359 | "source-map": "0.5.7", 360 | "trim-right": "1.0.1" 361 | } 362 | }, 363 | "babel-messages": { 364 | "version": "6.23.0", 365 | "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", 366 | "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", 367 | "requires": { 368 | "babel-runtime": "6.26.0" 369 | } 370 | }, 371 | "babel-runtime": { 372 | "version": "6.26.0", 373 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", 374 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", 375 | "requires": { 376 | "core-js": "2.5.1", 377 | "regenerator-runtime": "0.11.0" 378 | }, 379 | "dependencies": { 380 | "core-js": { 381 | "version": "2.5.1", 382 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", 383 | "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" 384 | } 385 | } 386 | }, 387 | "babel-template": { 388 | "version": "6.26.0", 389 | "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", 390 | "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", 391 | "requires": { 392 | "babel-runtime": "6.26.0", 393 | "babel-traverse": "6.26.0", 394 | "babel-types": "6.26.0", 395 | "babylon": "6.18.0", 396 | "lodash": "4.17.4" 397 | } 398 | }, 399 | "babel-traverse": { 400 | "version": "6.26.0", 401 | "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", 402 | "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", 403 | "requires": { 404 | "babel-code-frame": "6.26.0", 405 | "babel-messages": "6.23.0", 406 | "babel-runtime": "6.26.0", 407 | "babel-types": "6.26.0", 408 | "babylon": "6.18.0", 409 | "debug": "2.6.9", 410 | "globals": "9.18.0", 411 | "invariant": "2.2.2", 412 | "lodash": "4.17.4" 413 | }, 414 | "dependencies": { 415 | "debug": { 416 | "version": "2.6.9", 417 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 418 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 419 | "requires": { 420 | "ms": "2.0.0" 421 | } 422 | } 423 | } 424 | }, 425 | "babel-types": { 426 | "version": "6.26.0", 427 | "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", 428 | "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", 429 | "requires": { 430 | "babel-runtime": "6.26.0", 431 | "esutils": "2.0.2", 432 | "lodash": "4.17.4", 433 | "to-fast-properties": "1.0.3" 434 | } 435 | }, 436 | "babylon": { 437 | "version": "6.18.0", 438 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", 439 | "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" 440 | }, 441 | "balanced-match": { 442 | "version": "1.0.0", 443 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 444 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 445 | }, 446 | "base64-js": { 447 | "version": "0.0.8", 448 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", 449 | "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=" 450 | }, 451 | "benchmark": { 452 | "version": "2.1.4", 453 | "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", 454 | "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", 455 | "requires": { 456 | "lodash": "4.17.4", 457 | "platform": "1.3.4" 458 | } 459 | }, 460 | "bl": { 461 | "version": "1.2.1", 462 | "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", 463 | "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", 464 | "requires": { 465 | "readable-stream": "2.3.3" 466 | } 467 | }, 468 | "body-parser": { 469 | "version": "1.17.2", 470 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", 471 | "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", 472 | "requires": { 473 | "bytes": "2.4.0", 474 | "content-type": "1.0.4", 475 | "debug": "2.6.7", 476 | "depd": "1.1.1", 477 | "http-errors": "1.6.2", 478 | "iconv-lite": "0.4.15", 479 | "on-finished": "2.3.0", 480 | "qs": "6.4.0", 481 | "raw-body": "2.2.0", 482 | "type-is": "1.6.15" 483 | } 484 | }, 485 | "brace-expansion": { 486 | "version": "1.1.8", 487 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 488 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 489 | "requires": { 490 | "balanced-match": "1.0.0", 491 | "concat-map": "0.0.1" 492 | } 493 | }, 494 | "buffer": { 495 | "version": "3.6.0", 496 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", 497 | "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", 498 | "requires": { 499 | "base64-js": "0.0.8", 500 | "ieee754": "1.1.8", 501 | "isarray": "1.0.0" 502 | } 503 | }, 504 | "buffer-crc32": { 505 | "version": "0.2.13", 506 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 507 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" 508 | }, 509 | "bytes": { 510 | "version": "2.4.0", 511 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", 512 | "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" 513 | }, 514 | "camelcase": { 515 | "version": "1.2.1", 516 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 517 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 518 | "optional": true 519 | }, 520 | "center-align": { 521 | "version": "0.1.3", 522 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 523 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 524 | "optional": true, 525 | "requires": { 526 | "align-text": "0.1.4", 527 | "lazy-cache": "1.0.4" 528 | } 529 | }, 530 | "chai": { 531 | "version": "4.1.2", 532 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", 533 | "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", 534 | "requires": { 535 | "assertion-error": "1.0.2", 536 | "check-error": "1.0.2", 537 | "deep-eql": "3.0.1", 538 | "get-func-name": "2.0.0", 539 | "pathval": "1.1.0", 540 | "type-detect": "4.0.5" 541 | } 542 | }, 543 | "chalk": { 544 | "version": "1.1.3", 545 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 546 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 547 | "requires": { 548 | "ansi-styles": "2.2.1", 549 | "escape-string-regexp": "1.0.5", 550 | "has-ansi": "2.0.0", 551 | "strip-ansi": "3.0.1", 552 | "supports-color": "2.0.0" 553 | } 554 | }, 555 | "charm": { 556 | "version": "1.0.2", 557 | "resolved": "https://registry.npmjs.org/charm/-/charm-1.0.2.tgz", 558 | "integrity": "sha1-it02cVOm2aWBMxBSxAkJkdqZXjU=", 559 | "requires": { 560 | "inherits": "2.0.3" 561 | } 562 | }, 563 | "check-error": { 564 | "version": "1.0.2", 565 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 566 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" 567 | }, 568 | "cliui": { 569 | "version": "2.1.0", 570 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 571 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 572 | "optional": true, 573 | "requires": { 574 | "center-align": "0.1.3", 575 | "right-align": "0.1.3", 576 | "wordwrap": "0.0.2" 577 | }, 578 | "dependencies": { 579 | "wordwrap": { 580 | "version": "0.0.2", 581 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 582 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 583 | "optional": true 584 | } 585 | } 586 | }, 587 | "commander": { 588 | "version": "2.8.1", 589 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", 590 | "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", 591 | "requires": { 592 | "graceful-readlink": "1.0.1" 593 | } 594 | }, 595 | "concat-map": { 596 | "version": "0.0.1", 597 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 598 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 599 | }, 600 | "content-disposition": { 601 | "version": "0.5.2", 602 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 603 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 604 | }, 605 | "content-type": { 606 | "version": "1.0.4", 607 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 608 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 609 | }, 610 | "cookie": { 611 | "version": "0.3.1", 612 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 613 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 614 | }, 615 | "cookie-signature": { 616 | "version": "1.0.6", 617 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 618 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 619 | }, 620 | "core-js": { 621 | "version": "2.3.0", 622 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", 623 | "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=" 624 | }, 625 | "core-util-is": { 626 | "version": "1.0.2", 627 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 628 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 629 | }, 630 | "debug": { 631 | "version": "2.6.7", 632 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", 633 | "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", 634 | "requires": { 635 | "ms": "2.0.0" 636 | } 637 | }, 638 | "decamelize": { 639 | "version": "1.2.0", 640 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 641 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 642 | "optional": true 643 | }, 644 | "decompress": { 645 | "version": "4.2.0", 646 | "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", 647 | "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", 648 | "requires": { 649 | "decompress-tar": "4.1.1", 650 | "decompress-tarbz2": "4.1.1", 651 | "decompress-targz": "4.1.1", 652 | "decompress-unzip": "4.0.1", 653 | "graceful-fs": "4.1.11", 654 | "make-dir": "1.1.0", 655 | "pify": "2.3.0", 656 | "strip-dirs": "2.1.0" 657 | } 658 | }, 659 | "decompress-tar": { 660 | "version": "4.1.1", 661 | "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", 662 | "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", 663 | "requires": { 664 | "file-type": "5.2.0", 665 | "is-stream": "1.1.0", 666 | "tar-stream": "1.5.5" 667 | } 668 | }, 669 | "decompress-tarbz2": { 670 | "version": "4.1.1", 671 | "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", 672 | "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", 673 | "requires": { 674 | "decompress-tar": "4.1.1", 675 | "file-type": "6.2.0", 676 | "is-stream": "1.1.0", 677 | "seek-bzip": "1.0.5", 678 | "unbzip2-stream": "1.2.5" 679 | }, 680 | "dependencies": { 681 | "file-type": { 682 | "version": "6.2.0", 683 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", 684 | "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==" 685 | } 686 | } 687 | }, 688 | "decompress-targz": { 689 | "version": "4.1.1", 690 | "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", 691 | "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", 692 | "requires": { 693 | "decompress-tar": "4.1.1", 694 | "file-type": "5.2.0", 695 | "is-stream": "1.1.0" 696 | } 697 | }, 698 | "decompress-unzip": { 699 | "version": "4.0.1", 700 | "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", 701 | "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", 702 | "requires": { 703 | "file-type": "3.9.0", 704 | "get-stream": "2.3.1", 705 | "pify": "2.3.0", 706 | "yauzl": "2.9.1" 707 | }, 708 | "dependencies": { 709 | "file-type": { 710 | "version": "3.9.0", 711 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", 712 | "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=" 713 | } 714 | } 715 | }, 716 | "deep-eql": { 717 | "version": "3.0.1", 718 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 719 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 720 | "requires": { 721 | "type-detect": "4.0.5" 722 | } 723 | }, 724 | "default-require-extensions": { 725 | "version": "1.0.0", 726 | "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", 727 | "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", 728 | "requires": { 729 | "strip-bom": "2.0.0" 730 | } 731 | }, 732 | "depd": { 733 | "version": "1.1.1", 734 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", 735 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" 736 | }, 737 | "destroy": { 738 | "version": "1.0.4", 739 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 740 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 741 | }, 742 | "detect-indent": { 743 | "version": "4.0.0", 744 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", 745 | "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", 746 | "requires": { 747 | "repeating": "2.0.1" 748 | } 749 | }, 750 | "diff": { 751 | "version": "3.2.0", 752 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", 753 | "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=" 754 | }, 755 | "ee-first": { 756 | "version": "1.1.1", 757 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 758 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 759 | }, 760 | "encodeurl": { 761 | "version": "1.0.1", 762 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", 763 | "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" 764 | }, 765 | "end-of-stream": { 766 | "version": "1.4.0", 767 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", 768 | "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", 769 | "requires": { 770 | "once": "1.4.0" 771 | } 772 | }, 773 | "es6-promise": { 774 | "version": "3.0.2", 775 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", 776 | "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=" 777 | }, 778 | "escape-html": { 779 | "version": "1.0.3", 780 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 781 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 782 | }, 783 | "escape-string-regexp": { 784 | "version": "1.0.5", 785 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 786 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 787 | }, 788 | "esutils": { 789 | "version": "2.0.2", 790 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 791 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" 792 | }, 793 | "etag": { 794 | "version": "1.8.1", 795 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 796 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 797 | }, 798 | "express": { 799 | "version": "4.15.5", 800 | "resolved": "https://registry.npmjs.org/express/-/express-4.15.5.tgz", 801 | "integrity": "sha1-ZwI1ypWYiQpa6BcLg9tyK4Qu2Sc=", 802 | "requires": { 803 | "accepts": "1.3.4", 804 | "array-flatten": "1.1.1", 805 | "content-disposition": "0.5.2", 806 | "content-type": "1.0.4", 807 | "cookie": "0.3.1", 808 | "cookie-signature": "1.0.6", 809 | "debug": "2.6.9", 810 | "depd": "1.1.1", 811 | "encodeurl": "1.0.1", 812 | "escape-html": "1.0.3", 813 | "etag": "1.8.1", 814 | "finalhandler": "1.0.6", 815 | "fresh": "0.5.2", 816 | "merge-descriptors": "1.0.1", 817 | "methods": "1.1.2", 818 | "on-finished": "2.3.0", 819 | "parseurl": "1.3.2", 820 | "path-to-regexp": "0.1.7", 821 | "proxy-addr": "1.1.5", 822 | "qs": "6.5.0", 823 | "range-parser": "1.2.0", 824 | "send": "0.15.6", 825 | "serve-static": "1.12.6", 826 | "setprototypeof": "1.0.3", 827 | "statuses": "1.3.1", 828 | "type-is": "1.6.15", 829 | "utils-merge": "1.0.0", 830 | "vary": "1.1.2" 831 | }, 832 | "dependencies": { 833 | "debug": { 834 | "version": "2.6.9", 835 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 836 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 837 | "requires": { 838 | "ms": "2.0.0" 839 | } 840 | }, 841 | "qs": { 842 | "version": "6.5.0", 843 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", 844 | "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==" 845 | } 846 | } 847 | }, 848 | "fd-slicer": { 849 | "version": "1.0.1", 850 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", 851 | "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", 852 | "requires": { 853 | "pend": "1.2.0" 854 | } 855 | }, 856 | "file-type": { 857 | "version": "5.2.0", 858 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", 859 | "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" 860 | }, 861 | "finalhandler": { 862 | "version": "1.0.6", 863 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz", 864 | "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=", 865 | "requires": { 866 | "debug": "2.6.9", 867 | "encodeurl": "1.0.1", 868 | "escape-html": "1.0.3", 869 | "on-finished": "2.3.0", 870 | "parseurl": "1.3.2", 871 | "statuses": "1.3.1", 872 | "unpipe": "1.0.0" 873 | }, 874 | "dependencies": { 875 | "debug": { 876 | "version": "2.6.9", 877 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 878 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 879 | "requires": { 880 | "ms": "2.0.0" 881 | } 882 | } 883 | } 884 | }, 885 | "forwarded": { 886 | "version": "0.1.2", 887 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 888 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 889 | }, 890 | "fresh": { 891 | "version": "0.5.2", 892 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 893 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 894 | }, 895 | "fs.realpath": { 896 | "version": "1.0.0", 897 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 898 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 899 | }, 900 | "get-func-name": { 901 | "version": "2.0.0", 902 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 903 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" 904 | }, 905 | "get-stream": { 906 | "version": "2.3.1", 907 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", 908 | "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", 909 | "requires": { 910 | "object-assign": "4.1.1", 911 | "pinkie-promise": "2.0.1" 912 | } 913 | }, 914 | "glob": { 915 | "version": "7.1.2", 916 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 917 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 918 | "requires": { 919 | "fs.realpath": "1.0.0", 920 | "inflight": "1.0.6", 921 | "inherits": "2.0.3", 922 | "minimatch": "3.0.4", 923 | "once": "1.4.0", 924 | "path-is-absolute": "1.0.1" 925 | } 926 | }, 927 | "globals": { 928 | "version": "9.18.0", 929 | "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", 930 | "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" 931 | }, 932 | "graceful-fs": { 933 | "version": "4.1.11", 934 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 935 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 936 | }, 937 | "graceful-readlink": { 938 | "version": "1.0.1", 939 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", 940 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" 941 | }, 942 | "handlebars": { 943 | "version": "4.0.11", 944 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", 945 | "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", 946 | "requires": { 947 | "async": "1.5.2", 948 | "optimist": "0.6.1", 949 | "source-map": "0.4.4", 950 | "uglify-js": "2.8.29" 951 | }, 952 | "dependencies": { 953 | "source-map": { 954 | "version": "0.4.4", 955 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", 956 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", 957 | "requires": { 958 | "amdefine": "1.0.1" 959 | } 960 | } 961 | } 962 | }, 963 | "has-ansi": { 964 | "version": "2.0.0", 965 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 966 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 967 | "requires": { 968 | "ansi-regex": "2.1.1" 969 | } 970 | }, 971 | "has-flag": { 972 | "version": "1.0.0", 973 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", 974 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" 975 | }, 976 | "http-errors": { 977 | "version": "1.6.2", 978 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", 979 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", 980 | "requires": { 981 | "depd": "1.1.1", 982 | "inherits": "2.0.3", 983 | "setprototypeof": "1.0.3", 984 | "statuses": "1.3.1" 985 | } 986 | }, 987 | "iconv-lite": { 988 | "version": "0.4.15", 989 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", 990 | "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=" 991 | }, 992 | "ieee754": { 993 | "version": "1.1.8", 994 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", 995 | "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" 996 | }, 997 | "immediate": { 998 | "version": "3.0.6", 999 | "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", 1000 | "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" 1001 | }, 1002 | "inflight": { 1003 | "version": "1.0.6", 1004 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1005 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1006 | "requires": { 1007 | "once": "1.4.0", 1008 | "wrappy": "1.0.2" 1009 | } 1010 | }, 1011 | "inherits": { 1012 | "version": "2.0.3", 1013 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1014 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 1015 | }, 1016 | "intern": { 1017 | "version": "4.1.2", 1018 | "resolved": "https://registry.npmjs.org/intern/-/intern-4.1.2.tgz", 1019 | "integrity": "sha512-R4hJ+PUkp733rVtq5ndIlVmYS5JDLjueYR0vJq1OHwOFoQv2fMcIZMdNGyZh2KbNa4PlTeZOA4934tF7Tkc/IQ==", 1020 | "requires": { 1021 | "@dojo/core": "0.1.0", 1022 | "@dojo/has": "0.1.0", 1023 | "@dojo/interfaces": "0.1.0", 1024 | "@dojo/shim": "0.1.0", 1025 | "@theintern/digdug": "2.0.3", 1026 | "@theintern/leadfoot": "2.0.2", 1027 | "@types/benchmark": "1.0.31", 1028 | "@types/chai": "4.0.5", 1029 | "@types/charm": "1.0.1", 1030 | "@types/diff": "3.2.2", 1031 | "@types/express": "4.0.39", 1032 | "@types/http-errors": "1.5.34", 1033 | "@types/istanbul-lib-coverage": "1.1.0", 1034 | "@types/istanbul-lib-hook": "1.0.0", 1035 | "@types/istanbul-lib-instrument": "1.7.0", 1036 | "@types/istanbul-lib-report": "1.1.0", 1037 | "@types/istanbul-lib-source-maps": "1.2.0", 1038 | "@types/istanbul-reports": "1.1.0", 1039 | "@types/lodash": "4.14.85", 1040 | "@types/mime-types": "2.1.0", 1041 | "@types/platform": "1.3.1", 1042 | "@types/resolve": "0.0.4", 1043 | "@types/shell-quote": "1.6.0", 1044 | "@types/source-map": "0.1.29", 1045 | "@types/statuses": "1.2.28", 1046 | "@types/ws": "0.0.42", 1047 | "benchmark": "2.1.4", 1048 | "body-parser": "1.17.2", 1049 | "chai": "4.1.2", 1050 | "charm": "1.0.2", 1051 | "diff": "3.2.0", 1052 | "express": "4.15.5", 1053 | "glob": "7.1.2", 1054 | "http-errors": "1.6.2", 1055 | "istanbul-lib-coverage": "1.1.1", 1056 | "istanbul-lib-hook": "1.0.7", 1057 | "istanbul-lib-instrument": "1.7.5", 1058 | "istanbul-lib-report": "1.1.2", 1059 | "istanbul-lib-source-maps": "1.2.2", 1060 | "istanbul-reports": "1.1.3", 1061 | "lodash": "4.17.4", 1062 | "mime-types": "2.1.17", 1063 | "minimatch": "3.0.4", 1064 | "platform": "1.3.4", 1065 | "resolve": "1.4.0", 1066 | "shell-quote": "1.6.1", 1067 | "source-map": "0.5.7", 1068 | "statuses": "1.3.1", 1069 | "tslib": "1.8.0", 1070 | "ws": "2.3.1" 1071 | } 1072 | }, 1073 | "invariant": { 1074 | "version": "2.2.2", 1075 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", 1076 | "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", 1077 | "requires": { 1078 | "loose-envify": "1.3.1" 1079 | } 1080 | }, 1081 | "ipaddr.js": { 1082 | "version": "1.4.0", 1083 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", 1084 | "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=" 1085 | }, 1086 | "is-buffer": { 1087 | "version": "1.1.6", 1088 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1089 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1090 | }, 1091 | "is-finite": { 1092 | "version": "1.0.2", 1093 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 1094 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 1095 | "requires": { 1096 | "number-is-nan": "1.0.1" 1097 | } 1098 | }, 1099 | "is-natural-number": { 1100 | "version": "4.0.1", 1101 | "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", 1102 | "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=" 1103 | }, 1104 | "is-stream": { 1105 | "version": "1.1.0", 1106 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 1107 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 1108 | }, 1109 | "is-utf8": { 1110 | "version": "0.2.1", 1111 | "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", 1112 | "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" 1113 | }, 1114 | "isarray": { 1115 | "version": "1.0.0", 1116 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1117 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 1118 | }, 1119 | "istanbul-lib-coverage": { 1120 | "version": "1.1.1", 1121 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", 1122 | "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==" 1123 | }, 1124 | "istanbul-lib-hook": { 1125 | "version": "1.0.7", 1126 | "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", 1127 | "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", 1128 | "requires": { 1129 | "append-transform": "0.4.0" 1130 | } 1131 | }, 1132 | "istanbul-lib-instrument": { 1133 | "version": "1.7.5", 1134 | "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.5.tgz", 1135 | "integrity": "sha1-rbWW+PDLi5XnOSBjUaOKWGryGx4=", 1136 | "requires": { 1137 | "babel-generator": "6.26.0", 1138 | "babel-template": "6.26.0", 1139 | "babel-traverse": "6.26.0", 1140 | "babel-types": "6.26.0", 1141 | "babylon": "6.18.0", 1142 | "istanbul-lib-coverage": "1.1.1", 1143 | "semver": "5.4.1" 1144 | } 1145 | }, 1146 | "istanbul-lib-report": { 1147 | "version": "1.1.2", 1148 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.2.tgz", 1149 | "integrity": "sha512-UTv4VGx+HZivJQwAo1wnRwe1KTvFpfi/NYwN7DcsrdzMXwpRT/Yb6r4SBPoHWj4VuQPakR32g4PUUeyKkdDkBA==", 1150 | "requires": { 1151 | "istanbul-lib-coverage": "1.1.1", 1152 | "mkdirp": "0.5.1", 1153 | "path-parse": "1.0.5", 1154 | "supports-color": "3.2.3" 1155 | }, 1156 | "dependencies": { 1157 | "supports-color": { 1158 | "version": "3.2.3", 1159 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", 1160 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 1161 | "requires": { 1162 | "has-flag": "1.0.0" 1163 | } 1164 | } 1165 | } 1166 | }, 1167 | "istanbul-lib-source-maps": { 1168 | "version": "1.2.2", 1169 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.2.tgz", 1170 | "integrity": "sha512-8BfdqSfEdtip7/wo1RnrvLpHVEd8zMZEDmOFEnpC6dg0vXflHt9nvoAyQUzig2uMSXfF2OBEYBV3CVjIL9JvaQ==", 1171 | "requires": { 1172 | "debug": "3.1.0", 1173 | "istanbul-lib-coverage": "1.1.1", 1174 | "mkdirp": "0.5.1", 1175 | "rimraf": "2.6.2", 1176 | "source-map": "0.5.7" 1177 | }, 1178 | "dependencies": { 1179 | "debug": { 1180 | "version": "3.1.0", 1181 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1182 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1183 | "requires": { 1184 | "ms": "2.0.0" 1185 | } 1186 | } 1187 | } 1188 | }, 1189 | "istanbul-reports": { 1190 | "version": "1.1.3", 1191 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.3.tgz", 1192 | "integrity": "sha512-ZEelkHh8hrZNI5xDaKwPMFwDsUf5wIEI2bXAFGp1e6deR2mnEKBPhLJEgr4ZBt8Gi6Mj38E/C8kcy9XLggVO2Q==", 1193 | "requires": { 1194 | "handlebars": "4.0.11" 1195 | } 1196 | }, 1197 | "js-tokens": { 1198 | "version": "3.0.2", 1199 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1200 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" 1201 | }, 1202 | "jsesc": { 1203 | "version": "1.3.0", 1204 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", 1205 | "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" 1206 | }, 1207 | "jsonify": { 1208 | "version": "0.0.0", 1209 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", 1210 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" 1211 | }, 1212 | "jszip": { 1213 | "version": "3.1.5", 1214 | "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz", 1215 | "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==", 1216 | "requires": { 1217 | "core-js": "2.3.0", 1218 | "es6-promise": "3.0.2", 1219 | "lie": "3.1.1", 1220 | "pako": "1.0.6", 1221 | "readable-stream": "2.0.6" 1222 | }, 1223 | "dependencies": { 1224 | "readable-stream": { 1225 | "version": "2.0.6", 1226 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", 1227 | "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", 1228 | "requires": { 1229 | "core-util-is": "1.0.2", 1230 | "inherits": "2.0.3", 1231 | "isarray": "1.0.0", 1232 | "process-nextick-args": "1.0.7", 1233 | "string_decoder": "0.10.31", 1234 | "util-deprecate": "1.0.2" 1235 | } 1236 | }, 1237 | "string_decoder": { 1238 | "version": "0.10.31", 1239 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1240 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 1241 | } 1242 | } 1243 | }, 1244 | "kind-of": { 1245 | "version": "3.2.2", 1246 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1247 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1248 | "requires": { 1249 | "is-buffer": "1.1.6" 1250 | } 1251 | }, 1252 | "lazy-cache": { 1253 | "version": "1.0.4", 1254 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 1255 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 1256 | "optional": true 1257 | }, 1258 | "lie": { 1259 | "version": "3.1.1", 1260 | "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", 1261 | "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", 1262 | "requires": { 1263 | "immediate": "3.0.6" 1264 | } 1265 | }, 1266 | "lodash": { 1267 | "version": "4.17.4", 1268 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 1269 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 1270 | }, 1271 | "longest": { 1272 | "version": "1.0.1", 1273 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 1274 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" 1275 | }, 1276 | "loose-envify": { 1277 | "version": "1.3.1", 1278 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 1279 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 1280 | "requires": { 1281 | "js-tokens": "3.0.2" 1282 | } 1283 | }, 1284 | "make-dir": { 1285 | "version": "1.1.0", 1286 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.1.0.tgz", 1287 | "integrity": "sha512-0Pkui4wLJ7rxvmfUvs87skoEaxmu0hCUApF8nonzpl7q//FWp9zu8W61Scz4sd/kUiqDxvUhtoam2efDyiBzcA==", 1288 | "requires": { 1289 | "pify": "3.0.0" 1290 | }, 1291 | "dependencies": { 1292 | "pify": { 1293 | "version": "3.0.0", 1294 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 1295 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 1296 | } 1297 | } 1298 | }, 1299 | "media-typer": { 1300 | "version": "0.3.0", 1301 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1302 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1303 | }, 1304 | "merge-descriptors": { 1305 | "version": "1.0.1", 1306 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1307 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 1308 | }, 1309 | "methods": { 1310 | "version": "1.1.2", 1311 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1312 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1313 | }, 1314 | "mime": { 1315 | "version": "1.3.4", 1316 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", 1317 | "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" 1318 | }, 1319 | "mime-db": { 1320 | "version": "1.30.0", 1321 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", 1322 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" 1323 | }, 1324 | "mime-types": { 1325 | "version": "2.1.17", 1326 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", 1327 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", 1328 | "requires": { 1329 | "mime-db": "1.30.0" 1330 | } 1331 | }, 1332 | "minimatch": { 1333 | "version": "3.0.4", 1334 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1335 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1336 | "requires": { 1337 | "brace-expansion": "1.1.8" 1338 | } 1339 | }, 1340 | "minimist": { 1341 | "version": "0.0.8", 1342 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1343 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 1344 | }, 1345 | "mkdirp": { 1346 | "version": "0.5.1", 1347 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1348 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1349 | "requires": { 1350 | "minimist": "0.0.8" 1351 | } 1352 | }, 1353 | "ms": { 1354 | "version": "2.0.0", 1355 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1356 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1357 | }, 1358 | "negotiator": { 1359 | "version": "0.6.1", 1360 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 1361 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 1362 | }, 1363 | "number-is-nan": { 1364 | "version": "1.0.1", 1365 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 1366 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 1367 | }, 1368 | "object-assign": { 1369 | "version": "4.1.1", 1370 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1371 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1372 | }, 1373 | "on-finished": { 1374 | "version": "2.3.0", 1375 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1376 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1377 | "requires": { 1378 | "ee-first": "1.1.1" 1379 | } 1380 | }, 1381 | "once": { 1382 | "version": "1.4.0", 1383 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1384 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1385 | "requires": { 1386 | "wrappy": "1.0.2" 1387 | } 1388 | }, 1389 | "optimist": { 1390 | "version": "0.6.1", 1391 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 1392 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 1393 | "requires": { 1394 | "minimist": "0.0.8", 1395 | "wordwrap": "0.0.3" 1396 | } 1397 | }, 1398 | "pako": { 1399 | "version": "1.0.6", 1400 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", 1401 | "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==" 1402 | }, 1403 | "parseurl": { 1404 | "version": "1.3.2", 1405 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 1406 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 1407 | }, 1408 | "path-is-absolute": { 1409 | "version": "1.0.1", 1410 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1411 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1412 | }, 1413 | "path-parse": { 1414 | "version": "1.0.5", 1415 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 1416 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" 1417 | }, 1418 | "path-to-regexp": { 1419 | "version": "0.1.7", 1420 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1421 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1422 | }, 1423 | "pathval": { 1424 | "version": "1.1.0", 1425 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 1426 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" 1427 | }, 1428 | "pend": { 1429 | "version": "1.2.0", 1430 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 1431 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" 1432 | }, 1433 | "pify": { 1434 | "version": "2.3.0", 1435 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1436 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" 1437 | }, 1438 | "pinkie": { 1439 | "version": "2.0.4", 1440 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1441 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" 1442 | }, 1443 | "pinkie-promise": { 1444 | "version": "2.0.1", 1445 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1446 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1447 | "requires": { 1448 | "pinkie": "2.0.4" 1449 | } 1450 | }, 1451 | "platform": { 1452 | "version": "1.3.4", 1453 | "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz", 1454 | "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=" 1455 | }, 1456 | "process-nextick-args": { 1457 | "version": "1.0.7", 1458 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 1459 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" 1460 | }, 1461 | "proxy-addr": { 1462 | "version": "1.1.5", 1463 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", 1464 | "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", 1465 | "requires": { 1466 | "forwarded": "0.1.2", 1467 | "ipaddr.js": "1.4.0" 1468 | } 1469 | }, 1470 | "qs": { 1471 | "version": "6.4.0", 1472 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", 1473 | "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" 1474 | }, 1475 | "range-parser": { 1476 | "version": "1.2.0", 1477 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 1478 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 1479 | }, 1480 | "raw-body": { 1481 | "version": "2.2.0", 1482 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", 1483 | "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", 1484 | "requires": { 1485 | "bytes": "2.4.0", 1486 | "iconv-lite": "0.4.15", 1487 | "unpipe": "1.0.0" 1488 | } 1489 | }, 1490 | "readable-stream": { 1491 | "version": "2.3.3", 1492 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 1493 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 1494 | "requires": { 1495 | "core-util-is": "1.0.2", 1496 | "inherits": "2.0.3", 1497 | "isarray": "1.0.0", 1498 | "process-nextick-args": "1.0.7", 1499 | "safe-buffer": "5.1.1", 1500 | "string_decoder": "1.0.3", 1501 | "util-deprecate": "1.0.2" 1502 | } 1503 | }, 1504 | "regenerator-runtime": { 1505 | "version": "0.11.0", 1506 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", 1507 | "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" 1508 | }, 1509 | "repeat-string": { 1510 | "version": "1.6.1", 1511 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 1512 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" 1513 | }, 1514 | "repeating": { 1515 | "version": "2.0.1", 1516 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 1517 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 1518 | "requires": { 1519 | "is-finite": "1.0.2" 1520 | } 1521 | }, 1522 | "resolve": { 1523 | "version": "1.4.0", 1524 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", 1525 | "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", 1526 | "requires": { 1527 | "path-parse": "1.0.5" 1528 | } 1529 | }, 1530 | "right-align": { 1531 | "version": "0.1.3", 1532 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 1533 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 1534 | "optional": true, 1535 | "requires": { 1536 | "align-text": "0.1.4" 1537 | } 1538 | }, 1539 | "rimraf": { 1540 | "version": "2.6.2", 1541 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 1542 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 1543 | "requires": { 1544 | "glob": "7.1.2" 1545 | } 1546 | }, 1547 | "safe-buffer": { 1548 | "version": "5.1.1", 1549 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 1550 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 1551 | }, 1552 | "seek-bzip": { 1553 | "version": "1.0.5", 1554 | "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", 1555 | "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", 1556 | "requires": { 1557 | "commander": "2.8.1" 1558 | } 1559 | }, 1560 | "semver": { 1561 | "version": "5.4.1", 1562 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", 1563 | "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" 1564 | }, 1565 | "send": { 1566 | "version": "0.15.6", 1567 | "resolved": "https://registry.npmjs.org/send/-/send-0.15.6.tgz", 1568 | "integrity": "sha1-IPI6nJJbdiq4JwX+L52yUqzkfjQ=", 1569 | "requires": { 1570 | "debug": "2.6.9", 1571 | "depd": "1.1.1", 1572 | "destroy": "1.0.4", 1573 | "encodeurl": "1.0.1", 1574 | "escape-html": "1.0.3", 1575 | "etag": "1.8.1", 1576 | "fresh": "0.5.2", 1577 | "http-errors": "1.6.2", 1578 | "mime": "1.3.4", 1579 | "ms": "2.0.0", 1580 | "on-finished": "2.3.0", 1581 | "range-parser": "1.2.0", 1582 | "statuses": "1.3.1" 1583 | }, 1584 | "dependencies": { 1585 | "debug": { 1586 | "version": "2.6.9", 1587 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1588 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1589 | "requires": { 1590 | "ms": "2.0.0" 1591 | } 1592 | } 1593 | } 1594 | }, 1595 | "serve-static": { 1596 | "version": "1.12.6", 1597 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.6.tgz", 1598 | "integrity": "sha1-uXN3P2NEmTTaVOW+ul4x2fQhFXc=", 1599 | "requires": { 1600 | "encodeurl": "1.0.1", 1601 | "escape-html": "1.0.3", 1602 | "parseurl": "1.3.2", 1603 | "send": "0.15.6" 1604 | } 1605 | }, 1606 | "setprototypeof": { 1607 | "version": "1.0.3", 1608 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", 1609 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" 1610 | }, 1611 | "shell-quote": { 1612 | "version": "1.6.1", 1613 | "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", 1614 | "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", 1615 | "requires": { 1616 | "array-filter": "0.0.1", 1617 | "array-map": "0.0.0", 1618 | "array-reduce": "0.0.0", 1619 | "jsonify": "0.0.0" 1620 | } 1621 | }, 1622 | "source-map": { 1623 | "version": "0.5.7", 1624 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1625 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" 1626 | }, 1627 | "statuses": { 1628 | "version": "1.3.1", 1629 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", 1630 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" 1631 | }, 1632 | "string_decoder": { 1633 | "version": "1.0.3", 1634 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 1635 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 1636 | "requires": { 1637 | "safe-buffer": "5.1.1" 1638 | } 1639 | }, 1640 | "strip-ansi": { 1641 | "version": "3.0.1", 1642 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1643 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1644 | "requires": { 1645 | "ansi-regex": "2.1.1" 1646 | } 1647 | }, 1648 | "strip-bom": { 1649 | "version": "2.0.0", 1650 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", 1651 | "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", 1652 | "requires": { 1653 | "is-utf8": "0.2.1" 1654 | } 1655 | }, 1656 | "strip-dirs": { 1657 | "version": "2.1.0", 1658 | "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", 1659 | "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", 1660 | "requires": { 1661 | "is-natural-number": "4.0.1" 1662 | } 1663 | }, 1664 | "supports-color": { 1665 | "version": "2.0.0", 1666 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 1667 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" 1668 | }, 1669 | "tar-stream": { 1670 | "version": "1.5.5", 1671 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", 1672 | "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", 1673 | "requires": { 1674 | "bl": "1.2.1", 1675 | "end-of-stream": "1.4.0", 1676 | "readable-stream": "2.3.3", 1677 | "xtend": "4.0.1" 1678 | } 1679 | }, 1680 | "through": { 1681 | "version": "2.3.8", 1682 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1683 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 1684 | }, 1685 | "to-fast-properties": { 1686 | "version": "1.0.3", 1687 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", 1688 | "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" 1689 | }, 1690 | "trim-right": { 1691 | "version": "1.0.1", 1692 | "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", 1693 | "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" 1694 | }, 1695 | "tslib": { 1696 | "version": "1.8.0", 1697 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.8.0.tgz", 1698 | "integrity": "sha512-ymKWWZJST0/CkgduC2qkzjMOWr4bouhuURNXCn/inEX0L57BnRG6FhX76o7FOnsjHazCjfU2LKeSrlS2sIKQJg==" 1699 | }, 1700 | "type-detect": { 1701 | "version": "4.0.5", 1702 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz", 1703 | "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==" 1704 | }, 1705 | "type-is": { 1706 | "version": "1.6.15", 1707 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", 1708 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", 1709 | "requires": { 1710 | "media-typer": "0.3.0", 1711 | "mime-types": "2.1.17" 1712 | } 1713 | }, 1714 | "typescript": { 1715 | "version": "2.6.1", 1716 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.1.tgz", 1717 | "integrity": "sha1-7znN6ierrAtQAkLWcmq5DgyEZjE=" 1718 | }, 1719 | "uglify-js": { 1720 | "version": "2.8.29", 1721 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", 1722 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", 1723 | "optional": true, 1724 | "requires": { 1725 | "source-map": "0.5.7", 1726 | "uglify-to-browserify": "1.0.2", 1727 | "yargs": "3.10.0" 1728 | } 1729 | }, 1730 | "uglify-to-browserify": { 1731 | "version": "1.0.2", 1732 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 1733 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 1734 | "optional": true 1735 | }, 1736 | "ultron": { 1737 | "version": "1.1.0", 1738 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.0.tgz", 1739 | "integrity": "sha1-sHoualQagV/Go0zNRTO67DB8qGQ=" 1740 | }, 1741 | "unbzip2-stream": { 1742 | "version": "1.2.5", 1743 | "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", 1744 | "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", 1745 | "requires": { 1746 | "buffer": "3.6.0", 1747 | "through": "2.3.8" 1748 | } 1749 | }, 1750 | "unpipe": { 1751 | "version": "1.0.0", 1752 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1753 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1754 | }, 1755 | "util-deprecate": { 1756 | "version": "1.0.2", 1757 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1758 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1759 | }, 1760 | "utils-merge": { 1761 | "version": "1.0.0", 1762 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", 1763 | "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" 1764 | }, 1765 | "vary": { 1766 | "version": "1.1.2", 1767 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1768 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1769 | }, 1770 | "window-size": { 1771 | "version": "0.1.0", 1772 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 1773 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 1774 | "optional": true 1775 | }, 1776 | "wordwrap": { 1777 | "version": "0.0.3", 1778 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 1779 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" 1780 | }, 1781 | "wrappy": { 1782 | "version": "1.0.2", 1783 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1784 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1785 | }, 1786 | "ws": { 1787 | "version": "2.3.1", 1788 | "resolved": "https://registry.npmjs.org/ws/-/ws-2.3.1.tgz", 1789 | "integrity": "sha1-a5Sz5EfLajY/eF6vlK9jWejoHIA=", 1790 | "requires": { 1791 | "safe-buffer": "5.0.1", 1792 | "ultron": "1.1.0" 1793 | }, 1794 | "dependencies": { 1795 | "safe-buffer": { 1796 | "version": "5.0.1", 1797 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", 1798 | "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=" 1799 | } 1800 | } 1801 | }, 1802 | "xtend": { 1803 | "version": "4.0.1", 1804 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 1805 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 1806 | }, 1807 | "yargs": { 1808 | "version": "3.10.0", 1809 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 1810 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 1811 | "optional": true, 1812 | "requires": { 1813 | "camelcase": "1.2.1", 1814 | "cliui": "2.1.0", 1815 | "decamelize": "1.2.0", 1816 | "window-size": "0.1.0" 1817 | } 1818 | }, 1819 | "yauzl": { 1820 | "version": "2.9.1", 1821 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", 1822 | "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", 1823 | "requires": { 1824 | "buffer-crc32": "0.2.13", 1825 | "fd-slicer": "1.0.1" 1826 | } 1827 | } 1828 | } 1829 | } 1830 | -------------------------------------------------------------------------------- /examples/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "intern-a11y-TS-example", 3 | "private": true, 4 | "dependencies": { 5 | "intern": "~4.1.0", 6 | "@theintern/a11y": "file:../../_build/src", 7 | "rimraf": "~2.6.2", 8 | "typescript": "~2.6.0" 9 | }, 10 | "scripts": { 11 | "test": "intern", 12 | "build": "tsc", 13 | "clean": "rimraf a11y-report 'tests/**/*.js'" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/ts/tests/axe.ts: -------------------------------------------------------------------------------- 1 | import { check, createChecker } from '@theintern/a11y/services/axe'; 2 | import { join } from 'path'; 3 | 4 | const { registerSuite } = intern.getInterface('object'); 5 | const { assert } = intern.getPlugin('chai'); 6 | 7 | registerSuite('aXe', { 8 | 'external page'() { 9 | return this.remote 10 | .get('http://google.com') 11 | .sleep(2000) 12 | .then(createChecker()); 13 | }, 14 | 15 | 'file name'() { 16 | return check({ 17 | remote: this.remote, 18 | source: join(__dirname, 'data', 'page.html') 19 | }); 20 | }, 21 | 22 | 'bad page'() { 23 | return check({ 24 | remote: this.remote, 25 | source: join(__dirname, 'data', 'bad_page.html') 26 | }); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /examples/ts/tests/data/bad_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test page 5 | 6 | 7 | 15 | 16 |
17 |

Testing

18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/ts/tests/data/page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test page 5 | 6 | 7 |

Test page

8 | Search 9 | 10 | 11 | -------------------------------------------------------------------------------- /examples/ts/tests/interfaces.ts: -------------------------------------------------------------------------------- 1 | export type TestModuleInit = (registerSuite: Function) => void 2 | 3 | export interface TestModule { 4 | init: TestModuleInit 5 | } 6 | -------------------------------------------------------------------------------- /examples/ts/tests/tenon.ts: -------------------------------------------------------------------------------- 1 | import { check } from '@theintern/a11y/services/tenon'; 2 | import { join } from 'path'; 3 | 4 | const { registerSuite } = intern.getInterface('object'); 5 | const { assert } = intern.getPlugin('chai'); 6 | 7 | const keyPresent = process.env['TENON_API_KEY'] != null; 8 | 9 | registerSuite('tenon', { 10 | 'external url'() { 11 | if (!keyPresent) { 12 | this.skip('missing Tenon API key'); 13 | } 14 | return check({ source: 'http://tenon.io/documentation' }); 15 | }, 16 | 17 | 'file name'() { 18 | if (!keyPresent) { 19 | this.skip('missing Tenon API key'); 20 | } 21 | return check({ source: join(__dirname, 'data', 'page.html') }); 22 | }, 23 | 24 | 'bad page'() { 25 | if (!keyPresent) { 26 | this.skip('missing Tenon API key'); 27 | } 28 | return check({ source: join(__dirname, 'data', 'bad_page.html') }); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /examples/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "moduleResolution": "node", 5 | "strict": true, 6 | "target": "es2015", 7 | "types": ["intern"] 8 | }, 9 | "include": ["./tests/**/*.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /intern.json: -------------------------------------------------------------------------------- 1 | { 2 | "capabilities": { "name": "intern-a11y" }, 3 | "environments": [ 4 | "node", 5 | { 6 | "browserName": "chrome", 7 | "fixSessionCapabilities": false 8 | } 9 | ], 10 | "node": { 11 | "suites": [ 12 | "_build/tests/unit/**/*.js", 13 | "_build/tests/integration/tenon.js" 14 | ] 15 | }, 16 | "functionalSuites": "_build/tests/integration/axe.js", 17 | "coverage": "_build/src/**/*.js", 18 | "filterErrorStack": true 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@theintern/a11y", 3 | "version": "0.2.1-pre", 4 | "description": "Intern-a11y. An accessibility testing helper for Intern.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/theintern/intern-a11y.git" 8 | }, 9 | "license": "BSD-3-Clause", 10 | "dependencies": { 11 | "@types/mkdirp": "~0.5.1", 12 | "axe-core": "~2.5.0", 13 | "mkdirp": "~0.5.1" 14 | }, 15 | "devDependencies": { 16 | "@theintern/dev": "~0.6.2", 17 | "intern": "~4.1.2" 18 | }, 19 | "peerDependencies": { 20 | "intern": "~4.1.0" 21 | }, 22 | "bugs": "https://github.com/theintern/intern-a11y/issues", 23 | "keywords": [ 24 | "javascript", 25 | "test", 26 | "functional", 27 | "tenon", 28 | "aXe" 29 | ], 30 | "homepage": "http://github.com/theintern/intern-a11y", 31 | "scripts": { 32 | "build": "intern-dev-clean && intern-dev-build && intern-dev-api", 33 | "clean": "intern-dev-clean", 34 | "lint": "intern-dev-lint", 35 | "release": "intern-dev-release", 36 | "test": "NODE_PATH=_build intern", 37 | "watch": "intern-dev-watch" 38 | }, 39 | "internDev": { 40 | "resources": { 41 | "_build": [ 42 | "tests/**/*.{html,json}" 43 | ] 44 | }, 45 | "configs": [ 46 | "tsconfig.json", 47 | "tests/tsconfig.json" 48 | ], 49 | "publishDir": "_build/src" 50 | }, 51 | "prettier": { 52 | "singleQuote": true, 53 | "tabWidth": 4, 54 | "useTabs": true 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/A11yReporter.ts: -------------------------------------------------------------------------------- 1 | import { join, dirname } from 'path'; 2 | import { sync as mkdir } from 'mkdirp'; 3 | import { writeFile, writeFileSync } from 'fs'; 4 | import Test from 'intern/lib/Test'; 5 | import Suite from 'intern/lib/Suite'; 6 | import { Executor } from 'intern/lib/executors/Executor'; 7 | import { A11yResults, A11yViolation } from './common'; 8 | 9 | /** 10 | * A11yReporter writes test results to a file or a directory of files. 11 | */ 12 | export default class A11yReporter { 13 | executor: Executor; 14 | filename: string; 15 | console: Console; 16 | 17 | protected _report: string[] | undefined; 18 | protected _reportFiles: string[]; 19 | 20 | /** 21 | * WriteReport writes a set of A11yResults to a file 22 | */ 23 | static writeReport(filename: string, results: A11yResults, id: string) { 24 | return new Promise((resolve, reject) => { 25 | const content = renderResults(results, id); 26 | writeFile(filename, renderReport(content), error => { 27 | if (error) { 28 | reject(error); 29 | } else { 30 | resolve(results); 31 | } 32 | }); 33 | }); 34 | } 35 | 36 | constructor(executor: Executor, options?: A11yReporterOptions) { 37 | this.executor = executor; 38 | 39 | options = options || {}; 40 | this.filename = options.filename || 'a11y-report'; 41 | this.console = options.console || console; 42 | 43 | const reportDir = dirname(this.filename); 44 | if (reportDir !== '.') { 45 | mkdir(reportDir); 46 | } 47 | 48 | if (/\.html$/.test(this.filename)) { 49 | // Filename is a single HTML file that will contain multiple 50 | // individual reports 51 | this._report = []; 52 | this._reportFiles = [this.filename]; 53 | } else { 54 | this._reportFiles = []; 55 | 56 | // Filename is a directory that will store multiple reports, one 57 | // per file. 58 | mkdir(this.filename); 59 | } 60 | 61 | executor.on('runEnd', this.runEnd.bind(this)); 62 | executor.on('suiteEnd', this.suiteEnd.bind(this)); 63 | executor.on('testEnd', this.testEnd.bind(this)); 64 | } 65 | 66 | testEnd(test: Test) { 67 | // We only care about failing tests 68 | if (!test.error) { 69 | return; 70 | } 71 | 72 | const error = test.error; 73 | let results: A11yResults = (error).a11yResults; 74 | 75 | if (results) { 76 | const content = renderResults(results, test.id); 77 | 78 | if (this._report) { 79 | // Add this report to the reports list 80 | this._report.push(content); 81 | } else { 82 | // Write this report to a file 83 | const filename = join( 84 | this.filename, 85 | sanitizeFilename(test.id + '.html') 86 | ); 87 | writeFileSync(filename, renderReport(content)); 88 | this._reportFiles.push(filename); 89 | } 90 | } 91 | } 92 | 93 | runEnd() { 94 | if (this._reportFiles.length > 0) { 95 | this.console.log(); 96 | for (const file of this._reportFiles) { 97 | this.console.log(`A11y report written to ${file}`); 98 | } 99 | this.console.log(); 100 | } 101 | } 102 | 103 | suiteEnd(suite: Suite) { 104 | if (!suite.hasParent) { 105 | if (this._report) { 106 | writeFileSync( 107 | this.filename, 108 | renderReport(this._report.join('')) 109 | ); 110 | this._reportFiles.push(this.filename); 111 | } 112 | } 113 | } 114 | } 115 | 116 | export interface A11yReporterOptions { 117 | console?: Console; 118 | filename?: string; 119 | } 120 | 121 | if (typeof intern !== 'undefined') { 122 | intern.registerPlugin('A11yReporter', options => { 123 | new A11yReporter(intern, options); 124 | }); 125 | } 126 | 127 | function escape(str: string) { 128 | return String(str).replace(/ 133 | 134 | 135 | Accessibility Report 136 | 175 | 190 | 191 | 192 | ${body} 193 | 194 | `; 195 | } 196 | 197 | function renderResults(results: A11yResults, id: string) { 198 | let out: string[] = ['
']; 199 | 200 | out.push(`

${id}

`); 201 | out.push(`
    202 |
  • Analyzer ${results.analyzer}
  • 203 |
  • Source ${results.source}
  • 204 |
`); 205 | 206 | if (results.violations.length > 0) { 207 | out = out.concat(results.violations.map(renderViolation)); 208 | } else { 209 | out = out.concat('

No violations

'); 210 | } 211 | 212 | out.push(`
213 | 214 |
${escape(
215 | 			JSON.stringify(results.originalResults, null, '  ')
216 | 		)}
217 |
`); 218 | 219 | return out.concat('
').join(''); 220 | } 221 | 222 | function renderViolation(violation: A11yViolation) { 223 | let target = escape(violation.target); 224 | if (violation.position) { 225 | target += ` (${violation.position.line}:${violation.position.column})`; 226 | } 227 | 228 | let standards = ''; 229 | if (violation.standards && violation.standards.length > 0) { 230 | standards = `
231 |

Standards

232 |
    233 |
  • ${violation.standards.join('
  • ')}
  • 234 |
235 |
`; 236 | } 237 | 238 | return `
239 |
240 |

Target

${target}
241 | 244 |

Description

${escape( 245 | violation.description 246 | )}
247 | ${standards} 248 |
249 |
${escape(violation.snippet)}
250 |
`; 251 | } 252 | 253 | function sanitizeFilename(filename: string) { 254 | return filename.replace(/[/?<>\\:*|"]/g, '_').replace(/[.\s]+$/, ''); 255 | } 256 | -------------------------------------------------------------------------------- /src/common.ts: -------------------------------------------------------------------------------- 1 | export interface A11yViolation { 2 | message: string; 3 | snippet: string; 4 | description: string; 5 | target: string; 6 | reference: string; 7 | standards: string[]; 8 | position?: { 9 | line: number, 10 | column: number 11 | }; 12 | } 13 | 14 | export interface A11yResults { 15 | analyzer: string; 16 | source: string; 17 | violations: A11yViolation[]; 18 | originalResults: any; 19 | } 20 | 21 | export class A11yError extends Error { 22 | a11yResults: A11yResults; 23 | 24 | constructor(message: string, results: A11yResults) { 25 | super(message); 26 | ( Error).captureStackTrace(this, this.constructor); 27 | this.message = message; 28 | this.a11yResults = results; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as axe from './services/axe'; 2 | import * as tenon from './services/tenon'; 3 | import A11yReporter from './A11yReporter'; 4 | 5 | export const services = { 6 | axe, 7 | tenon 8 | }; 9 | 10 | export { A11yReporter }; 11 | export * from './common'; 12 | -------------------------------------------------------------------------------- /src/services/_axe.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This module exports "private" functions and interfaces for testing purposes. 3 | * It is is not meant to be loaded directly by end users. 4 | */ 5 | 6 | import { A11yResults } from '../common'; 7 | 8 | export interface AxeCheck { 9 | id: string; 10 | impact: string; 11 | message: string; 12 | data: string; 13 | relatedNodes: { 14 | target: string[], 15 | html: string 16 | }[]; 17 | } 18 | 19 | export interface AxeResult { 20 | description: string; 21 | help: string; 22 | helpUrl: string; 23 | id: string; 24 | impact: string; 25 | tags: string[]; 26 | nodes: { 27 | html: string, 28 | impact: string, 29 | target: string[], 30 | any: AxeCheck[], 31 | all: AxeCheck[], 32 | none: AxeCheck[] 33 | }[]; 34 | } 35 | 36 | export interface AxeResults { 37 | url: string; 38 | timestamp: string; 39 | passes: AxeResult[]; 40 | violations: AxeResult[]; 41 | } 42 | 43 | export function toA11yResults(axeResults: AxeResults): A11yResults { 44 | return { 45 | analyzer: 'axe', 46 | source: axeResults.url, 47 | violations: axeResults.violations.map(function (violation) { 48 | let standards: string[] = []; 49 | let wcagLevel = ''; 50 | 51 | if (violation.tags.indexOf('wcag2a') !== -1) { 52 | wcagLevel = 'A'; 53 | } 54 | else if (violation.tags.indexOf('wcag2aa') !== -1) { 55 | wcagLevel = 'AA'; 56 | } 57 | else if (violation.tags.indexOf('wcag2aaa') !== -1) { 58 | wcagLevel = 'AAA'; 59 | } 60 | 61 | violation.tags.forEach(function (tag) { 62 | if (/wcag\d+$/.test(tag)) { 63 | const section = tag.slice(4).split('').join('.'); 64 | standards.push(`Web Content Accessibility Guidelines (WCAG) 2.0, Level ${wcagLevel}: ${section}`); 65 | } 66 | else if (/section508\..*/.test(tag)) { 67 | standards.push(`Section 508: 1194.${tag.slice('section508.'.length)}`); 68 | } 69 | else if (tag === 'best-practice') { 70 | standards.push('Best practice'); 71 | } 72 | else { 73 | standards.push(tag[0].toUpperCase() + tag.slice(1)); 74 | } 75 | }); 76 | 77 | return { 78 | message: violation.help, 79 | snippet: violation.nodes[0].html, 80 | description: violation.description, 81 | target: violation.nodes[0].target[0], 82 | reference: violation.helpUrl, 83 | standards: standards 84 | }; 85 | }), 86 | originalResults: axeResults 87 | }; 88 | } 89 | -------------------------------------------------------------------------------- /src/services/_tenon.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This module exports "private" functions and interfaces for testing purposes. 3 | * It is is not meant to be loaded directly by end users. 4 | */ 5 | 6 | import { A11yResults } from '../common'; 7 | import { statSync } from 'fs'; 8 | 9 | export interface TenonResults { 10 | apiErrors: any[]; 11 | documentSize: number; 12 | globalStats: { 13 | errorDensity: string, 14 | warningDensity: string, 15 | allDensity: string, 16 | stdDev: string 17 | }; 18 | message: string; 19 | request: { 20 | url: string, 21 | ref: string, 22 | importance: string, 23 | responseID: string, 24 | userID: string, 25 | uaString: string, 26 | projectID: string, 27 | docID: string, 28 | level: string, 29 | certainty: number, 30 | priority: number, 31 | waitFor: string, 32 | fragment: number, 33 | store: number, 34 | viewport: { 35 | height: number, 36 | width: number 37 | } 38 | }; 39 | responseExecTime: string; 40 | responseTime: string; 41 | resultSet: { 42 | bpID: number, 43 | certainty: number, 44 | errorDescription: string, 45 | errorSnippet: string, 46 | errorTitle: string, 47 | issueID: string, 48 | position: { 49 | line: number, 50 | column: number 51 | }; 52 | priority: number, 53 | ref: string, 54 | resultTitle: string, 55 | signature: string, 56 | standards: string[], 57 | tID: number, 58 | viewPortLocation: { 59 | 'bottom-right': { 60 | x: number, 61 | y: number 62 | }, 63 | 'top-left': { 64 | x: number, 65 | y: number 66 | }, 67 | height: number, 68 | width: number 69 | }, 70 | xpath: string 71 | }[]; 72 | resultSummary: { 73 | density: { 74 | allDensity: number, 75 | errorDensity: number, 76 | warningDensity: number 77 | }, 78 | issues: { 79 | totalErrors: number, 80 | totalIssues: number, 81 | totalWarnings: number 82 | }, 83 | issuesByLevel: { 84 | A: { 85 | count: number, 86 | pct: number 87 | }, 88 | AA: { 89 | count: number, 90 | pct: number 91 | } 92 | AAA: { 93 | count: number, 94 | pct: number 95 | } 96 | }, 97 | tests: { 98 | failing: number, 99 | passing: number, 100 | total: number 101 | } 102 | }; 103 | sourceHash: string; 104 | status: number; 105 | urlHttpCode: number; 106 | clientScriptErrors: { 107 | message: string, 108 | stacktrace: any[] 109 | }; 110 | code: string; 111 | moreInfo: string; 112 | } 113 | 114 | export function toA11yResults(tenonResults: TenonResults): A11yResults { 115 | let source = tenonResults.request.url; 116 | if (/tenon\.io\/api\/file.php/.test(tenonResults.request.url)) { 117 | source = `${tenonResults.request.docID} (uploaded)`; 118 | } 119 | 120 | return { 121 | analyzer: 'tenon', 122 | source: source, 123 | violations: tenonResults.resultSet.map(function (result) { 124 | return { 125 | message: result.errorTitle, 126 | snippet: result.errorSnippet, 127 | description: result.errorDescription, 128 | target: result.xpath, 129 | reference: result.ref, 130 | standards: result.standards, 131 | position: { 132 | line: result.position.line, 133 | column: result.position.column 134 | } 135 | }; 136 | }), 137 | originalResults: tenonResults 138 | }; 139 | } 140 | 141 | export function fileExists(filename: string) { 142 | try { 143 | return statSync(filename).isFile(); 144 | } 145 | catch (error) { 146 | if (error.code === 'ENOENT') { 147 | return false; 148 | } 149 | throw error; 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/services/axe.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs'; 2 | import { A11yResults, A11yError } from '../common'; 3 | import { AxeResults, toA11yResults } from './_axe'; 4 | import Command from '@theintern/leadfoot/Command'; 5 | 6 | export interface AxeTestOptions { 7 | /** aXe-specific config parameters */ 8 | config?: { 9 | branding?: { 10 | brand?: string; 11 | application?: string; 12 | }; 13 | reporter?: 'v1' | 'v2'; 14 | checks?: { 15 | id: string; 16 | evaluate: Function; 17 | after?: Function; 18 | options?: Object; 19 | matches?: string; 20 | enabled?: boolean; 21 | }[]; 22 | rules?: { 23 | id: string; 24 | selector?: string; 25 | excludeHidden?: boolean; 26 | enabled?: boolean; 27 | pageLevel?: boolean; 28 | any?: string[]; 29 | all?: string[]; 30 | none?: string[]; 31 | tags?: string[]; 32 | matches?: string; 33 | }[]; 34 | }; 35 | 36 | /** 37 | * The scope to be analyzed (i.e., a selector for a portion of a 38 | * document); defaults to the entire document 39 | */ 40 | context?: string; 41 | } 42 | 43 | export interface AxeRunTestOptions extends AxeTestOptions { 44 | /** LeadFoot Command object */ 45 | remote: Command; 46 | 47 | /** URL to load for testing */ 48 | source: string; 49 | 50 | /** Number of milliseconds to wait before starting test */ 51 | waitFor?: number; 52 | } 53 | 54 | /** 55 | * Create a checker function that will check a page for a11y violations using 56 | * aXe. 57 | */ 58 | export function createChecker( 59 | options?: AxeTestOptions 60 | ): () => Command { 61 | return function(this: Command) { 62 | options = options || {}; 63 | const axePath = require.resolve('axe-core/axe.min'); 64 | const axeScript = readFileSync(axePath, { encoding: 'utf8' }); 65 | const axeContext = options.context; 66 | 67 | const config = options.config; 68 | let axeConfig: AxeConfig | null = null; 69 | 70 | if (config) { 71 | axeConfig = { 72 | branding: config.branding, 73 | reporter: config.reporter, 74 | rules: config.rules 75 | }; 76 | if (config.checks) { 77 | axeConfig.checks = config.checks.map(function(check) { 78 | return { 79 | id: check.id, 80 | evaluate: check.evaluate.toString(), 81 | after: check.after ? check.after.toString() : undefined, 82 | options: check.options, 83 | matches: check.matches, 84 | enabled: check.enabled 85 | }; 86 | }); 87 | } 88 | } 89 | 90 | return this.parent 91 | .getExecuteAsyncTimeout() 92 | .then(function(this: Command, timeout: number) { 93 | return this.parent 94 | .setExecuteAsyncTimeout(30000) 95 | .execute(axeScript, []) 96 | .executeAsync( 97 | `return (function (config, context, done) { 98 | if (config) { 99 | if (config.checks) { 100 | config.checks.forEach(function (check) { 101 | eval('check.evaluate = ' + check.evaluate); 102 | if (check.after) { 103 | eval('check.after = ' + check.after); 104 | } 105 | }); 106 | } 107 | axe.configure(config); 108 | } 109 | if (!context) { 110 | context = document; 111 | } 112 | axe.a11yCheck(context, function(results) { 113 | done(results); 114 | }); 115 | }).apply(this, arguments)`, 116 | [axeConfig, axeContext] 117 | ) 118 | .then(function(results: AxeResults) { 119 | const a11yResults = toA11yResults(results); 120 | 121 | const numViolations = 122 | (results.violations && results.violations.length) || 123 | 0; 124 | let error: A11yError | undefined; 125 | if (numViolations === 1) { 126 | error = new A11yError( 127 | '1 a11y violation was logged', 128 | a11yResults 129 | ); 130 | } 131 | if (numViolations > 1) { 132 | error = new A11yError( 133 | numViolations + ' a11y violations were logged', 134 | a11yResults 135 | ); 136 | } 137 | 138 | if (error) { 139 | throw error; 140 | } 141 | 142 | return a11yResults; 143 | }) 144 | .then( 145 | function(results: A11yResults) { 146 | return this.parent 147 | .setExecuteAsyncTimeout(timeout) 148 | .then(function() { 149 | return results; 150 | }); 151 | }, 152 | function(error: Error) { 153 | return this.parent 154 | .setExecuteAsyncTimeout(timeout) 155 | .then(function() { 156 | throw error; 157 | }); 158 | } 159 | ); 160 | }); 161 | }; 162 | } 163 | 164 | /** 165 | * Check a page for a11y violations using aXe. 166 | */ 167 | export function check(options?: AxeRunTestOptions) { 168 | options = options || {}; 169 | 170 | if (options.remote == null) { 171 | return Promise.reject( 172 | new Error('A remote is required when calling check()') 173 | ); 174 | } 175 | if (options.source == null) { 176 | return Promise.reject( 177 | new Error('A source address is required when calling check()') 178 | ); 179 | } 180 | 181 | let chain = options.remote.get(options.source); 182 | 183 | if (options.waitFor) { 184 | chain = chain.sleep(options.waitFor); 185 | } 186 | 187 | return chain.then(createChecker(options)); 188 | } 189 | 190 | interface AxeConfig { 191 | branding?: { 192 | brand?: string; 193 | application?: string; 194 | }; 195 | reporter?: 'v1' | 'v2'; 196 | checks?: { 197 | id: string; 198 | evaluate: string; 199 | after?: string; 200 | options?: Object; 201 | matches?: string; 202 | enabled?: boolean; 203 | }[]; 204 | rules?: { 205 | id: string; 206 | selector?: string; 207 | excludeHidden?: boolean; 208 | enabled?: boolean; 209 | pageLevel?: boolean; 210 | any?: string[]; 211 | all?: string[]; 212 | none?: string[]; 213 | tags?: string[]; 214 | matches?: string; 215 | }[]; 216 | } 217 | -------------------------------------------------------------------------------- /src/services/tenon.ts: -------------------------------------------------------------------------------- 1 | import { request as httpsRequest } from 'https'; 2 | import { stringify } from 'querystring'; 3 | import { readFileSync } from 'fs'; 4 | import { A11yError, A11yResults } from '../common'; 5 | import { TenonResults, toA11yResults, fileExists } from './_tenon'; 6 | 7 | export interface TenonConfig { 8 | certainty?: 0 | 20 | 40 | 60 | 80 | 100; 9 | projectID?: string; 10 | docID?: string; 11 | priority?: 0 | 20 | 40 | 60 | 80 | 100; 12 | level?: 'A' | 'AA' | 'AAA'; 13 | fragment?: 0 | 1; 14 | store?: 0 | 1; 15 | uaString?: string; 16 | viewPortHeight?: number; 17 | viewPortWidth?: number; 18 | } 19 | 20 | export interface TenonTestOptions { 21 | /** An external URL, file name, or a data string */ 22 | source: string; 23 | 24 | /** tenon.io API key */ 25 | apiKey?: string; 26 | 27 | /** Number of milliseconds to wait before starting test */ 28 | waitFor?: number; 29 | 30 | /** Tenon configuration options */ 31 | config?: TenonConfig; 32 | } 33 | 34 | /** 35 | * Check a page for a11y violations using tenon. 36 | */ 37 | export function check(options: TenonTestOptions) { 38 | return new Promise(function(resolve, reject) { 39 | let apiKey = process.env['TENON_API_KEY']; 40 | if (!apiKey && options.apiKey) { 41 | apiKey = options.apiKey; 42 | } 43 | if (!apiKey) { 44 | throw new Error('tenon requires an API key'); 45 | } 46 | 47 | let queryData: TenonQuery = { 48 | key: apiKey 49 | }; 50 | 51 | // Copy user config into queryData 52 | if (options.config) { 53 | for (let key in options.config) { 54 | (queryData)[key] = (options.config)[key]; 55 | } 56 | } 57 | 58 | const source = options.source; 59 | 60 | if (/^https?:\/\/\S+$/.test(source)) { 61 | // source is a URL 62 | queryData.url = source; 63 | } else if (fileExists(source)) { 64 | // source is a file name 65 | queryData.src = readFileSync(source, { encoding: 'utf8' }); 66 | } else { 67 | // source is raw data 68 | queryData.src = source; 69 | } 70 | 71 | const data = stringify(queryData); 72 | 73 | const request = httpsRequest( 74 | { 75 | host: 'tenon.io', 76 | path: '/api/', 77 | method: 'POST', 78 | headers: { 79 | 'Content-Type': 'application/x-www-form-urlencoded', 80 | 'Content-Length': Buffer.byteLength(data) 81 | } 82 | }, 83 | function(response) { 84 | let responseData: string[] = []; 85 | response.setEncoding('utf8'); 86 | response.on('data', function(chunk: string) { 87 | responseData.push(chunk); 88 | }); 89 | response.on('end', function() { 90 | if (response.statusCode !== 200) { 91 | reject(new Error((response).statusMessage)); 92 | } else { 93 | resolve(JSON.parse(responseData.join(''))); 94 | } 95 | }); 96 | response.on('error', function(error: Error) { 97 | reject(error); 98 | }); 99 | } 100 | ); 101 | 102 | request.write(data); 103 | request.end(); 104 | }).then(function(results: TenonResults): A11yResults { 105 | const a11yResults = toA11yResults(results); 106 | const totalErrors = results.resultSummary.issues.totalErrors; 107 | let error: A11yError | undefined; 108 | 109 | if (totalErrors === 1) { 110 | error = new A11yError('1 a11y violation was logged', a11yResults); 111 | } 112 | if (totalErrors > 1) { 113 | error = new A11yError( 114 | totalErrors + ' a11y violations were logged', 115 | a11yResults 116 | ); 117 | } 118 | 119 | if (error) { 120 | throw error; 121 | } 122 | 123 | return a11yResults; 124 | }); 125 | } 126 | 127 | interface TenonQuery extends TenonConfig { 128 | key: string; 129 | src?: string; 130 | url?: string; 131 | } 132 | -------------------------------------------------------------------------------- /tests/data/a11y_results.json: -------------------------------------------------------------------------------- 1 | { 2 | "analyzer": "tenon", 3 | "source": "http://google.com", 4 | "violations": [ 5 | { 6 | "message": "Page has no headings", 7 | "snippet": "<body bgcolor=\"#fff\" style=\"\"><script>(function(){var src='/images/nav_logo229.png';var iesg=false;document.body.onload = function(){window.n && window.n();if (document.images){new Image().src=src;}\nif (!iesg){document.f&&docu", 8 | "description": "This page has no heading elements. Heading elements provide a number of important benefits to users. They can be useful as wayfinding cues for in-page navigation, they can contribute to a summary of the page, and they can provide context to the content below them.", 9 | "target": "/html/body", 10 | "reference": "https://tenon.io/bestpractice.php?bpID=28&tID=97", 11 | "tags": [ 12 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 1.3.1 Info and Relationships" 13 | ] 14 | }, 15 | { 16 | "message": "This form element has no label.", 17 | "snippet": "<input style=\"color: rgb(0, 0, 0); margin: 0px; padding: 5px 8px 0px 6px; vertical-align: top; outline: none;\" autocomplete=\"off\" class=\"lst\" value=\"\" title=\"Google Search\" maxlength=\"2048\" name=\"q\" size=\"57\" dir=\"ltr\" spellcheck=\"false\">", 18 | "description": "Give all controls a label. This allows all users to understand the type of information expected in the field.", 19 | "target": "/html/body/center[1]/form[1]/table[1]/tr[1]/td[2]/div[1]/input[1]", 20 | "reference": "https://tenon.io/bestpractice.php?bpID=49&tID=38", 21 | "tags": [ 22 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 1.1.1 Non-text Content", 23 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 1.3.1 Info and Relationships", 24 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 3.3.2 Labels or Instructions", 25 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 4.1.2 Name, Role, Value" 26 | ] 27 | }, 28 | { 29 | "message": "This link has no text inside it.", 30 | "snippet": "<a class=\"gbgt\" id=\"gbg5\" href=\"http://www.google.com/preferences?hl=en\" title=\"Options\" onclick=\"gbar.tg(event,this)\" aria-haspopup=\"true\" aria-owns=\"gbd5\"><span class=\"gbtb2\"></span><span id=\"gbgs5\" class=\"gbts\"><span id=\"gbi", 31 | "description": "This link has no text in it. Because accessibility APIs use a link's text to determine its accessible name, this link will not have an accessible name, and it will not be announced by assistive technologies. Add text within this link or use `aria-label` to give the link an accessible name.", 32 | "target": "/html/body/div[1]/div[1]/div[1]/div[2]/ol[1]/li[3]/a[1]", 33 | "reference": "https://tenon.io/bestpractice.php?bpID=106&tID=57", 34 | "tags": [ 35 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 2.4.4 Link Purpose (In Context)", 36 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level AAA: 2.4.9 Link Purpose (Link Only)" 37 | ] 38 | }, 39 | { 40 | "message": "This link text is uninformative.", 41 | "snippet": "<a class=\"gbgt\" id=\"gbztm\" href=\"https://www.google.com/intl/en/options/\" onclick=\"gbar.tg(event,this)\" aria-haspopup=\"true\" aria-owns=\"gbd\"><span class=\"gbtb2\"></span><span id=\"gbztms\" class=\"gbts gbtsa\"><span id=\"gbztms1\">", 42 | "description": "Do not use generic text in links. Use text in the link that accurately and concisely conveys where the link goes.", 43 | "target": "/html/body/div[1]/div[1]/div[1]/div[1]/ol[1]/li[9]/a[1]", 44 | "reference": "https://tenon.io/bestpractice.php?bpID=106&tID=73", 45 | "tags": [ 46 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 2.4.4 Link Purpose (In Context)", 47 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level AAA: 2.4.9 Link Purpose (Link Only)" 48 | ] 49 | }, 50 | { 51 | "message": "This table does not have any headers.", 52 | "snippet": "<table cellpadding=\"0\" cellspacing=\"0\"><tbody><tr valign=\"top\"><td width=\"25%\">&nbsp;</td><td align=\"center\" nowrap=\"\"><input value=\"en\" name=\"hl\" type=\"hidden\"><input name=\"source\" type=\"hidden\" value=\"hp", 53 | "description": "This table does not contain any `<th>` elements. If this table is used for layout, replace it with a proper layout controlled with CSS. If that's not possible, add `role="presentation"` to the table.", 54 | "target": "/html/body/center[1]/form[1]/table[1]", 55 | "reference": "https://tenon.io/bestpractice.php?bpID=131&tID=34", 56 | "tags": [ 57 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 1.3.1 Info and Relationships" 58 | ] 59 | } 60 | ] 61 | } 62 | -------------------------------------------------------------------------------- /tests/data/axe_results.json: -------------------------------------------------------------------------------- 1 | { 2 | "passes": [ 3 | { 4 | "help": "Elements must have sufficient color contrast", 5 | "nodes": [ 6 | { 7 | "all": [], 8 | "impact": null, 9 | "html": "

Testing

", 10 | "none": [], 11 | "any": [ 12 | { 13 | "id": "color-contrast", 14 | "data": { 15 | "contrastRatio": "21.00", 16 | "fgColor": "#000000", 17 | "fontSize": "24.0pt", 18 | "bgColor": "#ffffff", 19 | "fontWeight": "bold" 20 | }, 21 | "message": "Element has sufficient color contrast of 21.00", 22 | "impact": "critical", 23 | "relatedNodes": [] 24 | } 25 | ], 26 | "target": [ 27 | "#heading > h1" 28 | ] 29 | }, 30 | { 31 | "all": [], 32 | "impact": null, 33 | "html": "
Foo
", 34 | "none": [], 35 | "any": [ 36 | { 37 | "id": "color-contrast", 38 | "data": { 39 | "contrastRatio": "21.00", 40 | "fgColor": "#000000", 41 | "fontSize": "12.0pt", 42 | "bgColor": "#ffffff", 43 | "fontWeight": "normal" 44 | }, 45 | "message": "Element has sufficient color contrast of 21.00", 46 | "impact": "critical", 47 | "relatedNodes": [] 48 | } 49 | ], 50 | "target": [ 51 | "body > .bar" 52 | ] 53 | } 54 | ], 55 | "impact": null, 56 | "description": "Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds", 57 | "helpUrl": "https://dequeuniversity.com/rules/axe/2.0/color-contrast?application=axeAPI", 58 | "id": "color-contrast", 59 | "tags": [ 60 | "wcag2aa", 61 | "wcag143" 62 | ] 63 | }, 64 | { 65 | "help": "Documents must have element to aid in navigation", 66 | "nodes": [ 67 | { 68 | "all": [], 69 | "impact": null, 70 | "html": "<html>", 71 | "none": [], 72 | "any": [ 73 | { 74 | "id": "doc-has-title", 75 | "data": null, 76 | "message": "Document has a non-empty <title> element", 77 | "impact": "moderate", 78 | "relatedNodes": [] 79 | } 80 | ], 81 | "target": [ 82 | "html" 83 | ] 84 | } 85 | ], 86 | "impact": null, 87 | "description": "Ensures each HTML document contains a non-empty <title> element", 88 | "helpUrl": "https://dequeuniversity.com/rules/axe/2.0/document-title?application=axeAPI", 89 | "id": "document-title", 90 | "tags": [ 91 | "wcag2a", 92 | "wcag242" 93 | ] 94 | }, 95 | { 96 | "help": "id attribute value must be unique", 97 | "nodes": [ 98 | { 99 | "all": [], 100 | "impact": null, 101 | "html": "<div id=\"heading\">\n\t\t\t<h1>Testing</h1>\n\t\t</div>", 102 | "none": [], 103 | "any": [ 104 | { 105 | "id": "duplicate-id", 106 | "data": "heading", 107 | "message": "Document has no elements that share the same id attribute", 108 | "impact": "critical", 109 | "relatedNodes": [] 110 | } 111 | ], 112 | "target": [ 113 | "#heading" 114 | ] 115 | } 116 | ], 117 | "impact": null, 118 | "description": "Ensures every id attribute value is unique", 119 | "helpUrl": "https://dequeuniversity.com/rules/axe/2.0/duplicate-id?application=axeAPI", 120 | "id": "duplicate-id", 121 | "tags": [ 122 | "wcag2a", 123 | "wcag411" 124 | ] 125 | }, 126 | { 127 | "help": "Headings must not be empty", 128 | "nodes": [ 129 | { 130 | "all": [], 131 | "impact": null, 132 | "html": "<h1>Testing</h1>", 133 | "none": [], 134 | "any": [ 135 | { 136 | "id": "has-visible-text", 137 | "data": null, 138 | "message": "Element has text that is visible to screen readers", 139 | "impact": "critical", 140 | "relatedNodes": [] 141 | } 142 | ], 143 | "target": [ 144 | "#heading > h1" 145 | ] 146 | } 147 | ], 148 | "impact": null, 149 | "description": "Ensures headings have discernible text", 150 | "helpUrl": "https://dequeuniversity.com/rules/axe/2.0/empty-heading?application=axeAPI", 151 | "id": "empty-heading", 152 | "tags": [ 153 | "best-practice" 154 | ] 155 | } 156 | ], 157 | "url": "http://localhost:9000/dist/tests/data/bad_page.html", 158 | "violations": [ 159 | { 160 | "help": "<html> element must have a lang attribute", 161 | "nodes": [ 162 | { 163 | "all": [], 164 | "impact": "serious", 165 | "html": "<html>", 166 | "none": [], 167 | "any": [ 168 | { 169 | "id": "has-lang", 170 | "data": null, 171 | "message": "The <html> element does not have a lang attribute", 172 | "impact": "serious", 173 | "relatedNodes": [] 174 | } 175 | ], 176 | "target": [ 177 | "html" 178 | ] 179 | } 180 | ], 181 | "impact": "serious", 182 | "description": "Ensures every HTML document has a lang attribute", 183 | "helpUrl": "https://dequeuniversity.com/rules/axe/2.0/html-has-lang?application=axeAPI", 184 | "id": "html-has-lang", 185 | "tags": [ 186 | "wcag2a", 187 | "wcag311" 188 | ] 189 | } 190 | ], 191 | "timestamp": "2016-10-11T21:02:43.996Z" 192 | } 193 | -------------------------------------------------------------------------------- /tests/data/bad_fragment.html: -------------------------------------------------------------------------------- 1 | <img href="foo.gif"/> 2 | -------------------------------------------------------------------------------- /tests/data/bad_page.html: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html> 2 | <html> 3 | <head> 4 | <title>Test page 5 | 6 | 7 | 15 | 16 |
17 |

Testing

18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/data/good_fragment.html: -------------------------------------------------------------------------------- 1 |

Test page

2 | -------------------------------------------------------------------------------- /tests/data/good_page.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test page 5 | 6 | 7 |

Test page

8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/data/tenon_results.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiErrors": [], 3 | "documentSize": 5391, 4 | "globalStats": { 5 | "errorDensity": "63", 6 | "warningDensity": "3", 7 | "allDensity": "66", 8 | "stdDev": "212" 9 | }, 10 | "message": "success", 11 | "request": { 12 | "ref": "1", 13 | "importance": "1", 14 | "responseID": "9db7a56006d56d4c2129c58f789c4d97", 15 | "userID": "3770", 16 | "uaString": null, 17 | "projectID": "DEFAULT_PROJECT", 18 | "docID": "E34435C0-B8C3-6954-F894-79FAAFB2F40A", 19 | "url": "https://tenon.io/api/file.php?docID=E34435C0-B8C3-6954-F894-79FAAFB2F40A", 20 | "level": "AAA", 21 | "certainty": 0, 22 | "priority": 0, 23 | "waitFor": null, 24 | "fragment": 0, 25 | "store": 1, 26 | "viewport": { 27 | "height": 768, 28 | "width": 1024 29 | } 30 | }, 31 | "responseExecTime": "0.30", 32 | "responseTime": "2016-10-11T21:00:49+0000", 33 | "resultSet": [ 34 | { 35 | "bpID": 118, 36 | "certainty": 100, 37 | "errorDescription": "The language of the document has not been set. Set the document's language by adding the `lang` attribute to the `<html>` element using a ISO 639-1 language code.", 38 | "errorSnippet": "<html><head><script type=\"text/javascript\" src=\"https://bam.nr-data.net/1/536baadf7e?a=7381143&amp;v=995.3402600&amp;to=bgYGMkoCWEBWW0YKXVdMMRRRTFdDXhdUCl5cTRQOSA%3D%3D&amp;rst=163&amp;ref=https://tenon.io/api/file.php&", 39 | "errorTitle": "The language of this page is not set.", 40 | "issueID": "128516bb2be3e3916764b0b037e9fb53", 41 | "position": { 42 | "column": 1, 43 | "line": 1 44 | }, 45 | "priority": 77, 46 | "ref": "https://tenon.io/bestpractice.php?bpID=118&tID=3", 47 | "resultTitle": "Identify the page's language.", 48 | "signature": "3cc1161591cd0a1f606898e98ddeb0d6", 49 | "standards": [ 50 | "Web Content Accessibility Guidelines (WCAG) 2.0, Level A: 3.1.1 Language of Page" 51 | ], 52 | "tID": 3, 53 | "viewPortLocation": { 54 | "bottom-right": { 55 | "x": 1024, 56 | "y": 82 57 | }, 58 | "height": 82, 59 | "top-left": { 60 | "x": 0, 61 | "y": 0 62 | }, 63 | "width": 1024 64 | }, 65 | "xpath": "/html" 66 | } 67 | ], 68 | "resultSummary": { 69 | "density": { 70 | "allDensity": 19, 71 | "errorDensity": 19, 72 | "warningDensity": 0 73 | }, 74 | "issues": { 75 | "totalErrors": 1, 76 | "totalIssues": 1, 77 | "totalWarnings": 0 78 | }, 79 | "issuesByLevel": { 80 | "A": { 81 | "count": 1, 82 | "pct": 100 83 | }, 84 | "AA": { 85 | "count": 0, 86 | "pct": 0 87 | }, 88 | "AAA": { 89 | "count": 0, 90 | "pct": 0 91 | } 92 | }, 93 | "tests": { 94 | "failing": 1, 95 | "passing": 73, 96 | "total": 74 97 | } 98 | }, 99 | "sourceHash": "2f182bd874d391651f5f68a74555eaf9", 100 | "status": 200, 101 | "urlHttpCode": 200, 102 | "clientScriptErrors": [], 103 | "code": "success", 104 | "resultUrl": "https://tenon.io/history.php?responseID=9db7a56006d56d4c2129c58f789c4d97", 105 | "moreInfo": "https://tenon.io/documentation/understanding-response-codes.php#success" 106 | } 107 | -------------------------------------------------------------------------------- /tests/integration/axe.ts: -------------------------------------------------------------------------------- 1 | import registerSuite, { Tests } from 'intern/lib/interfaces/object'; 2 | import { createChecker, check } from 'src/services/axe'; 3 | import { A11yResults } from 'src/common'; 4 | 5 | const { assert } = intern.getPlugin('chai'); 6 | 7 | registerSuite('integration/aXe', { 8 | bad: (function() { 9 | function runCheck( 10 | promise: PromiseLike, 11 | errorMatcher?: RegExp 12 | ) { 13 | return promise.then( 14 | function() { 15 | throw new Error('test should not have passed'); 16 | }, 17 | function(error) { 18 | if (errorMatcher) { 19 | assert.match(error.message, errorMatcher); 20 | } else { 21 | assert.match(error.message, /\d+ a11y violation/); 22 | assert.property( 23 | error, 24 | 'a11yResults', 25 | 'expected results to be attached to error' 26 | ); 27 | } 28 | } 29 | ); 30 | } 31 | 32 | return { 33 | Command() { 34 | return runCheck( 35 | this.remote 36 | .get('tests/data/bad_page.html') 37 | .sleep(1000) 38 | .then(createChecker()) 39 | ); 40 | }, 41 | 42 | standalone() { 43 | return runCheck( 44 | check({ 45 | source: 'tests/data/bad_page.html', 46 | remote: this.remote, 47 | waitFor: 1000 48 | }) 49 | ); 50 | }, 51 | 52 | 'missing remote'() { 53 | return runCheck( 54 | check({ 55 | source: 'tests/data/good_page.html', 56 | remote: undefined 57 | }), 58 | /A remote is required/ 59 | ); 60 | } 61 | }; 62 | })(), 63 | 64 | good: { 65 | Command() { 66 | return this.remote 67 | .get('tests/data/good_page.html') 68 | .sleep(1000) 69 | .then(createChecker()); 70 | }, 71 | 72 | standalone() { 73 | return check({ 74 | source: 'tests/data/good_page.html', 75 | remote: this.remote, 76 | waitFor: 1000 77 | }); 78 | }, 79 | 80 | 'partial page'() { 81 | return check({ 82 | source: 'tests/data/bad_page.html', 83 | remote: this.remote, 84 | waitFor: 1000, 85 | context: '#heading' 86 | }); 87 | } 88 | } 89 | }); 90 | -------------------------------------------------------------------------------- /tests/integration/tenon.ts: -------------------------------------------------------------------------------- 1 | import registerSuite, { Tests } from 'intern/lib/interfaces/object'; 2 | import { join } from 'path'; 3 | 4 | import { readFileSync } from 'fs'; 5 | import * as tenon from 'src/services/tenon'; 6 | 7 | const { assert } = intern.getPlugin('chai'); 8 | 9 | const keyPresent = process.env['TENON_API_KEY'] != null; 10 | 11 | registerSuite('integration/tenon', { 12 | bad: (function() { 13 | function check(config: tenon.TenonTestOptions) { 14 | return tenon.check(config).then( 15 | function() { 16 | throw new Error('test should not have passed'); 17 | }, 18 | function(error) { 19 | assert.match(error.message, /\d+ a11y violation/); 20 | assert.property( 21 | error, 22 | 'a11yResults', 23 | 'expected results to be attached to error' 24 | ); 25 | } 26 | ); 27 | } 28 | 29 | return { 30 | 'external url'() { 31 | if (!keyPresent) { 32 | this.skip('missing API key'); 33 | } 34 | return check({ source: 'http://google.com' }); 35 | }, 36 | 37 | 'file name'() { 38 | if (!keyPresent) { 39 | this.skip('missing API key'); 40 | } 41 | return check({ source: 'tests/data/bad_page.html' }); 42 | }, 43 | 44 | 'file data'() { 45 | if (!keyPresent) { 46 | this.skip('missing API key'); 47 | } 48 | return check({ 49 | source: readFileSync( 50 | join(__dirname, '../data/bad_page.html'), 51 | { 52 | encoding: 'utf8' 53 | } 54 | ) 55 | }); 56 | }, 57 | 58 | fragment() { 59 | if (!keyPresent) { 60 | this.skip('missing API key'); 61 | } 62 | return check({ 63 | source: 'tests/data/bad_fragment.html', 64 | config: { fragment: 1 } 65 | }); 66 | } 67 | }; 68 | })(), 69 | 70 | good: { 71 | 'external url'() { 72 | if (!keyPresent) { 73 | this.skip('missing API key'); 74 | } 75 | return tenon.check({ 76 | source: 'http://tenon.io/documentation' 77 | }); 78 | }, 79 | 80 | 'file name'() { 81 | if (!keyPresent) { 82 | this.skip('missing API key'); 83 | } 84 | return tenon.check({ 85 | source: 'tests/data/good_page.html' 86 | }); 87 | }, 88 | 89 | fragment() { 90 | if (!keyPresent) { 91 | this.skip('missing API key'); 92 | } 93 | return tenon.check({ 94 | source: 'tests/data/good_fragment.html', 95 | config: { fragment: 1 } 96 | }); 97 | } 98 | } 99 | }); 100 | -------------------------------------------------------------------------------- /tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "..", 4 | "declaration": false, 5 | "paths": { 6 | "src/*": ["_build/src/*", "src/*"] 7 | }, 8 | "sourceMap": true, 9 | "types": ["intern"] 10 | }, 11 | "extends": "../tsconfig.json", 12 | "include": ["./**/*.ts"] 13 | } 14 | -------------------------------------------------------------------------------- /tests/unit/A11yReporter.ts: -------------------------------------------------------------------------------- 1 | import { readdirSync, readFileSync, rmdirSync, statSync, unlinkSync } from 'fs'; 2 | import { join } from 'path'; 3 | import Test from 'intern/lib/Test'; 4 | import { fileExists } from '../util'; 5 | import { A11yResults, A11yError } from 'src/common'; 6 | import A11yReporter from 'src/A11yReporter'; 7 | 8 | const { registerSuite } = intern.getInterface('object'); 9 | const { assert } = intern.getPlugin('chai'); 10 | 11 | let reportFile: string | null; 12 | 13 | function remove(path: string) { 14 | if (statSync(path).isDirectory()) { 15 | readdirSync(path) 16 | .map(file => join(path, file)) 17 | .forEach(remove); 18 | rmdirSync(path); 19 | } else { 20 | unlinkSync(path); 21 | } 22 | } 23 | 24 | const dataDir = join(__dirname, '../data'); 25 | 26 | const mockExecutor: any = { 27 | on() {} 28 | }; 29 | 30 | const mockConsole: any = { 31 | messages: [], 32 | log(message: string) { 33 | this.messages.push(message); 34 | }, 35 | reset() { 36 | this.messages = []; 37 | } 38 | }; 39 | 40 | registerSuite('unit/A11yReporter', { 41 | beforeEach() { 42 | mockConsole.reset(); 43 | }, 44 | 45 | afterEach() { 46 | if (reportFile) { 47 | remove(reportFile); 48 | reportFile = null; 49 | } 50 | }, 51 | 52 | tests: { 53 | 'manual report'() { 54 | const data = readFileSync(`${dataDir}/a11y_results.json`, { 55 | encoding: 'utf8' 56 | }); 57 | const results = JSON.parse(data); 58 | reportFile = '_tempreport.html'; 59 | return A11yReporter.writeReport(reportFile, results, 'foo').then( 60 | function() { 61 | assert.isTrue(fileExists(reportFile!)); 62 | } 63 | ); 64 | }, 65 | 66 | 'failure report': { 67 | // Expect reports for all tests to be output to a single file 68 | 'to file'() { 69 | reportFile = '_tempreport.html'; 70 | const reporter = new A11yReporter(mockExecutor, { 71 | console: mockConsole, 72 | filename: reportFile 73 | }); 74 | 75 | const data = readFileSync(`${dataDir}/a11y_results.json`, { 76 | encoding: 'utf8' 77 | }); 78 | const results = JSON.parse(data); 79 | 80 | const test1 = new Test({ name: 'test1', test: () => {} }); 81 | const test2 = new Test({ name: 'test2', test: () => {} }); 82 | test1.error = new A11yError('Oops', results); 83 | test2.error = new A11yError('Oops', results); 84 | 85 | reporter.testEnd(test1); 86 | reporter.testEnd(test2); 87 | assert.isFalse( 88 | fileExists(reportFile), 89 | 'did not expect report file to exist' 90 | ); 91 | 92 | reporter.suiteEnd({ hasParent: false }); 93 | reporter.runEnd(); 94 | assert.isTrue( 95 | fileExists(reportFile), 96 | 'exected report file to exist' 97 | ); 98 | 99 | assert.deepEqual(mockConsole.messages, [ 100 | undefined, 101 | 'A11y report written to _tempreport.html', 102 | 'A11y report written to _tempreport.html', 103 | undefined 104 | ]); 105 | }, 106 | 107 | // Expect report for each test to be output to an individual file, all in the same directory 108 | 'to directory'() { 109 | reportFile = '_tempreports'; 110 | const reporter = new A11yReporter(mockExecutor, { 111 | console: mockConsole, 112 | filename: reportFile 113 | }); 114 | 115 | const data = readFileSync(`${dataDir}/a11y_results.json`, { 116 | encoding: 'utf8' 117 | }); 118 | const results = JSON.parse(data); 119 | 120 | const test1 = new Test({ name: 'test1', test: () => {} }); 121 | const test2 = new Test({ name: 'test2', test: () => {} }); 122 | test1.error = new A11yError('Oops', results); 123 | test2.error = new A11yError('Oops', results); 124 | 125 | reporter.testEnd(test1); 126 | let entries = readdirSync(reportFile); 127 | assert.lengthOf( 128 | entries, 129 | 1, 130 | 'unexpected number of report files' 131 | ); 132 | 133 | reporter.testEnd(test2); 134 | entries = readdirSync(reportFile); 135 | assert.lengthOf( 136 | entries, 137 | 2, 138 | 'unexpected number of report files' 139 | ); 140 | 141 | assert.lengthOf(mockConsole.messages, 0); 142 | } 143 | } 144 | } 145 | }); 146 | -------------------------------------------------------------------------------- /tests/unit/axe.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs'; 2 | import { join } from 'path'; 3 | import { toA11yResults } from 'src/services/_axe'; 4 | 5 | const { registerSuite } = intern.getInterface('object'); 6 | const { assert } = intern.getPlugin('chai'); 7 | 8 | registerSuite('unit/aXe', { 9 | toA11yResults() { 10 | const data = readFileSync(join(__dirname, '../data/axe_results.json'), { 11 | encoding: 'utf8' 12 | }); 13 | const results: any = JSON.parse(data); 14 | const a11yResults = toA11yResults(results); 15 | assert.lengthOf( 16 | a11yResults.violations, 17 | 1, 18 | 'unexpected number of violations' 19 | ); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /tests/unit/tenon.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs'; 2 | import { join } from 'path'; 3 | import { TenonResults, toA11yResults } from 'src/services/_tenon'; 4 | 5 | const { registerSuite } = intern.getInterface('object'); 6 | const { assert } = intern.getPlugin('chai'); 7 | 8 | registerSuite('unit/tenon', { 9 | toA11yResults() { 10 | const data = readFileSync( 11 | join(__dirname, '../data/tenon_results.json'), 12 | { 13 | encoding: 'utf8' 14 | } 15 | ); 16 | const results: TenonResults = JSON.parse(data); 17 | const a11yResults = toA11yResults(results); 18 | assert.lengthOf( 19 | a11yResults.violations, 20 | 1, 21 | 'unexpected number of violations' 22 | ); 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /tests/util.ts: -------------------------------------------------------------------------------- 1 | import { statSync, unlinkSync } from 'fs'; 2 | 3 | export function cleanup(filename: string) { 4 | try { 5 | statSync(filename); 6 | unlinkSync(filename); 7 | } catch (error) { 8 | if (error.code !== 'ENOENT') { 9 | throw error; 10 | } 11 | } 12 | 13 | return filename; 14 | } 15 | 16 | export function fileExists(filename: string) { 17 | try { 18 | return statSync(filename).isFile(); 19 | } catch (error) { 20 | if (error.code !== 'ENOENT') { 21 | throw error; 22 | } 23 | return false; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./node_modules/@theintern/dev/tsconfig-base.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "importHelpers": true, 6 | "lib": ["es5", "es2015.promise", "es2015.symbol.wellknown", "dom"], 7 | "outDir": "./_build", 8 | "rootDir": ".", 9 | "types": ["intern"] 10 | }, 11 | "include": ["./src/**/*.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { "extends": "@theintern/dev/tslint.json" } 2 | --------------------------------------------------------------------------------