├── .gitignore ├── README.MD └── demo ├── react ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json └── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── index.css │ ├── index.js │ ├── initAnalytics.js │ ├── logo.svg │ └── serviceWorker.js └── simple ├── README.md ├── index.html ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | This repo is example how to self-host analytics.js. We built analytics.js from https://github.com/fivetran/analytics.js, which is a very slight fork of https://github.com/segmentio/analytics.js, and are hosting it at https://static.fivetran.com/scripts/analytics.js. 4 | 5 | # Running locally with NPM 6 | 7 | To run demo, go the `./demo/` folder, then run the following commands: 8 | - `npm install` 9 | - `npm start` 10 | -------------------------------------------------------------------------------- /demo/react/README.md: -------------------------------------------------------------------------------- 1 | # How to self-host analytics.js with react-router 2 | 3 | ## Initialize analytics.js 4 | 5 | To initialize analytics.js please read the [following article](../simple/README.md). 6 | 7 | ## Sync analytics.js page tracking with client-side routing (react-router v4) 8 | 9 | 1. Create browser history manually: 10 | ```js 11 | import { createBrowserHistory } from 'history'; 12 | 13 | const history = createBrowserHistory(); 14 | ``` 15 | 2. Track page with analytics.js each time when location is changed 16 | ```js 17 | // Track client routing 18 | history.listen(() => window['analytics'].page()); 19 | ``` 20 | 3. Provide this `history` to router: 21 | ```js 22 | 23 | {/*...*/} 24 | 25 | ``` 26 | -------------------------------------------------------------------------------- /demo/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.6.3", 7 | "react-dom": "^16.6.3", 8 | "react-router-dom": "^4.3.1", 9 | "react-scripts": "2.1.1" 10 | }, 11 | "scripts": { 12 | "start": "react-scripts start", 13 | "build": "react-scripts build", 14 | "test": "react-scripts test", 15 | "eject": "react-scripts eject" 16 | }, 17 | "eslintConfig": { 18 | "extends": "react-app" 19 | }, 20 | "browserslist": [ 21 | ">0.2%", 22 | "not dead", 23 | "not ie <= 11", 24 | "not op_mini all" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /demo/react/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fivetran/self-hosted-analytics-js/915a0fd997261f5308789072a2bdb29f659f5867/demo/react/public/favicon.ico -------------------------------------------------------------------------------- /demo/react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /demo/react/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /demo/react/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; 4 | } 5 | 6 | .App-header { 7 | background-color: #212121; 8 | min-height: 100vh; 9 | display: flex; 10 | flex-direction: column; 11 | align-items: center; 12 | justify-content: center; 13 | font-size: calc(10px + 6vmin); 14 | color: white; 15 | } 16 | 17 | .App-nav { 18 | position: relative; 19 | z-index: 1; 20 | } 21 | 22 | .App-link { 23 | color: #2e64ea; 24 | margin: 0 20px; 25 | font-size: calc(10px + 2vmin); 26 | } 27 | 28 | .App-info { 29 | color: #dcdcdc; 30 | position: absolute; 31 | top: 10px; 32 | right: 20px; 33 | } 34 | 35 | .App-info a { 36 | color: #dcdcdc; 37 | } 38 | 39 | button { 40 | background: #2e64ea; 41 | color: #dcdcdc; 42 | font-size: 18px; 43 | padding: 10px; 44 | border: none; 45 | border-radius: 3px; 46 | transition: background ease .4s; 47 | cursor: pointer; 48 | margin-bottom: 10px; 49 | } 50 | 51 | button:hover { 52 | background: #437aff; 53 | } 54 | 55 | button:active { 56 | background: #1a5fdd; 57 | } 58 | 59 | .button-description { 60 | font-size: 14px; 61 | } 62 | 63 | .loading { 64 | display: block; 65 | position: relative; 66 | margin: 10px auto 50px; 67 | width: 100px; 68 | height: 100px; 69 | 70 | } 71 | .loading-wrapper { 72 | position: absolute; 73 | overflow: hidden; 74 | top: 0; 75 | bottom: 0; 76 | left: 13.889%; 77 | right: 13.889%; 78 | } 79 | 80 | .rect1 { 81 | position: absolute; 82 | bottom: 0; 83 | left: 4.3%; 84 | background: #2e64ea; 85 | width: 18.078%; 86 | height: 24.8%; 87 | border-radius: 8%; 88 | transform: skew(20deg); 89 | animation: rect1 1.2s linear infinite; 90 | } 91 | 92 | .rect2 { 93 | position: absolute; 94 | bottom: 0; 95 | left: 23.9%; 96 | background: #2e64ea; 97 | width: 18.078%; 98 | height: 49.8%; 99 | border-radius: 8%; 100 | transform: skew(20deg); 101 | animation: rect2 1.2s linear infinite; 102 | -webkit-animation-delay: -1s; 103 | animation-delay: -1s; 104 | } 105 | 106 | .rect3 { 107 | position: absolute; 108 | bottom: 0; 109 | left: 38.2%; 110 | background: #2e64ea; 111 | width: 18.078%; 112 | height: 100%; 113 | border-radius: 8%; 114 | transform: skew(20deg); 115 | animation: rect3 1.2s linear infinite; 116 | -webkit-animation-delay: -0.8s; 117 | animation-delay: -0.8s; 118 | } 119 | 120 | .rect4 { 121 | position: absolute; 122 | top: 0; 123 | right: 27.9%; 124 | background: #2e64ea; 125 | width: 18.078%; 126 | height: 49.8%; 127 | border-radius: 8%; 128 | transform: skew(20deg); 129 | animation: rect4 1.2s linear infinite; 130 | -webkit-animation-delay: -0.5s; 131 | animation-delay: -0.5s; 132 | } 133 | 134 | .rect5 { 135 | position: absolute; 136 | top: 0; 137 | right: 6.3%; 138 | background: #2e64ea; 139 | width: 18.078%; 140 | height: 24.8%; 141 | border-radius: 8%; 142 | transform: skew(20deg); 143 | animation: rect5 1.2s linear infinite; 144 | -webkit-animation-delay: -0.4s; 145 | animation-delay: -0.4s; 146 | } 147 | 148 | @keyframes rect1 { 149 | 0%, 40%, 100% { 150 | background-color: #2e64ea; 151 | height: 25%; 152 | left: 4.3%; 153 | } 154 | 20% { 155 | background-color: #dcdcdc; 156 | height: 0; 157 | left: 11%; 158 | transform: skew(20deg); 159 | } 160 | } 161 | @keyframes rect2 { 162 | 0%, 40%, 100% { 163 | background-color: #2e64ea; 164 | left: 23.9%; 165 | height: 50%; 166 | } 167 | 20% { 168 | background-color: #dcdcdc; 169 | height: 0; 170 | left: 36.6%; 171 | } 172 | } 173 | @keyframes rect3 { 174 | 0%, 40%, 100% { 175 | background-color: #2e64ea; 176 | height: 100%; 177 | left: 38.2%; 178 | } 179 | 20% { 180 | background-color: #dcdcdc; 181 | height: 0; 182 | left: 64%; 183 | } 184 | } 185 | @keyframes rect4 { 186 | 0%, 40%, 100% { 187 | background-color: #2e64ea; 188 | height: 50%; 189 | right: 27.9%; 190 | } 191 | 20% { 192 | background-color: #dcdcdc; 193 | height: 0; 194 | right: 41%; 195 | } 196 | } 197 | @keyframes rect5 { 198 | 0%, 40%, 100% { 199 | background-color: #2e64ea; 200 | height: 25%; 201 | right: 6.3%; 202 | } 203 | 20% { 204 | background-color: #dcdcdc; 205 | height: 0; 206 | right: 13%; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /demo/react/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route, Link } from 'react-router-dom'; 3 | import { createBrowserHistory } from 'history'; 4 | import './App.css'; 5 | 6 | const history = createBrowserHistory(); 7 | 8 | // Track client routing 9 | history.listen(location => window['analytics'].page()); 10 | 11 | const App = () => ( 12 | 13 |
14 |

15 | View events at https://pipedream.com/r/enxqu2io6sdml 16 |

17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | 31 |
32 | 33 | 34 |
35 |
36 |
37 |
38 | ); 39 | 40 | const Home = () => ( 41 |

Home page

42 | ) 43 | 44 | const About = () => ( 45 | <> 46 |

About page

47 | 55 |
To track `React Demo Button Clicked` event.
56 | 57 | ) 58 | 59 | export default App; 60 | -------------------------------------------------------------------------------- /demo/react/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /demo/react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /demo/react/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import {initAnalytics} from './initAnalytics'; 6 | import * as serviceWorker from './serviceWorker'; 7 | 8 | // View this endpoint at https://pipedream.com/r/enxqu2io6sdml 9 | initAnalytics('enxqu2io6sdml.x.pipedream.net'); 10 | 11 | ReactDOM.render(, document.getElementById('root')); 12 | 13 | // If you want your app to work offline and load faster, you can change 14 | // unregister() to register() below. Note this comes with some pitfalls. 15 | // Learn more about service workers: http://bit.ly/CRA-PWA 16 | serviceWorker.unregister(); 17 | -------------------------------------------------------------------------------- /demo/react/src/initAnalytics.js: -------------------------------------------------------------------------------- 1 | export const initAnalytics = (webhookHost) => { 2 | // Create a queue, but don't obliterate an existing one! 3 | var analytics = window.analytics = window.analytics || []; 4 | 5 | // If the real analytics.js is already on the page return. 6 | if (analytics.initialize) return; 7 | 8 | // If the snippet was invoked already show an error. 9 | if (analytics.invoked) { 10 | if (window.console && console.error) { 11 | console.error('Segment snippet included twice.'); 12 | } 13 | return; 14 | } 15 | 16 | // Invoked flag, to make sure the snippet 17 | // is never invoked twice. 18 | analytics.invoked = true; 19 | 20 | // A list of the methods in Analytics.js to stub. 21 | analytics.methods = [ 22 | 'trackSubmit', 23 | 'trackClick', 24 | 'trackLink', 25 | 'trackForm', 26 | 'pageview', 27 | 'identify', 28 | 'reset', 29 | 'group', 30 | 'track', 31 | 'ready', 32 | 'alias', 33 | 'debug', 34 | 'page', 35 | 'once', 36 | 'off', 37 | 'on' 38 | ]; 39 | 40 | // Define a factory to create stubs. These are placeholders 41 | // for methods in Analytics.js so that you never have to wait 42 | // for it to load to actually record data. The `method` is 43 | // stored as the first argument, so we can replay the data. 44 | analytics.factory = function(method){ 45 | return function(){ 46 | var args = Array.prototype.slice.call(arguments); 47 | args.unshift(method); 48 | analytics.push(args); 49 | return analytics; 50 | }; 51 | }; 52 | 53 | // For each of our methods, generate a queueing stub. 54 | for (var i = 0; i < analytics.methods.length; i++) { 55 | var key = analytics.methods[i]; 56 | analytics[key] = analytics.factory(key); 57 | } 58 | 59 | // Define a method to load Analytics.js from our CDN, 60 | // and that will be sure to only ever load it once. 61 | analytics.load = function(key, options){ 62 | // Create an async script element based on your key. 63 | var stubAnalytics = analytics; 64 | var script = document.createElement('script'); 65 | script.type = 'text/javascript'; 66 | script.async = true; 67 | script.src = 'https://static.fivetran.com/scripts/analytics.js'; 68 | 69 | // Insert our script next to the first script element. 70 | var first = document.getElementsByTagName('script')[0]; 71 | first.parentNode.insertBefore(script, first); 72 | analytics._loadOptions = options; 73 | 74 | script.addEventListener('load', function() { 75 | window.analytics.initialize({ 76 | 'Segment.io': { 77 | apiKey: 'NO_KEY', 78 | apiHost: webhookHost 79 | } 80 | }); 81 | 82 | while (stubAnalytics.length > 0) { 83 | var item = stubAnalytics.shift(); 84 | var method = item.shift(); 85 | if (stubAnalytics[method]) window.analytics[method].apply(window.analytics, item); 86 | } 87 | }, false) 88 | }; 89 | 90 | // Add a version to keep track of what's in the wild. 91 | analytics.SNIPPET_VERSION = '4.1.0'; 92 | 93 | // Load Analytics.js with your key, which will automatically 94 | // load the tools you've enabled for your account. Boosh! 95 | analytics.load("NO_KEY"); 96 | 97 | // Make the first page call to load the integrations. If 98 | // you'd like to manually name or tag the page, edit or 99 | // move this call however you'd like. 100 | analytics.page(); 101 | } 102 | -------------------------------------------------------------------------------- /demo/react/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /demo/react/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read http://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit http://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /demo/simple/README.md: -------------------------------------------------------------------------------- 1 | # How to self-host analytics.js 2 | 3 | To run this demo, do `npm install && npm run-script start`. 4 | 5 | ## Preparation 6 | 7 | 1. Copy this snippet into the head of your site: 8 | 9 | ```html 10 | 116 | ``` 117 | 118 | 3. Replace `NO_KEY` with your own key, and replace `enxqu2io6sdml.x.pipedream.net` with your own collector. If you want to use Fivetran to collect your Segment events, follow steps 1 and 2 from this guide: https://fivetran.com/docs/events/segment/segment-webhooks-setup-guide. 119 | 120 | 4. Optionally, replace https://static.fivetran.com/scripts/analytics.js with your own self-hosted copy of https://github.com/fivetran/analytics.js 121 | 122 | 5. To learn about tracking additional events, see https://segment.com/docs/sources/website/analytics.js/ 123 | -------------------------------------------------------------------------------- /demo/simple/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Analytics.js 8 | 242 | 348 | 349 | 350 | 351 |
352 |

353 | View events at https://pipedream.com/r/enxqu2io6sdml 354 |

355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 | 366 |
To track `Simple Demo Button Clicked` event.
367 |
368 |
369 | 370 | 371 | 372 | -------------------------------------------------------------------------------- /demo/simple/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@zeit/schemas": { 8 | "version": "2.6.0", 9 | "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz", 10 | "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==" 11 | }, 12 | "accepts": { 13 | "version": "1.3.5", 14 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 15 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 16 | "requires": { 17 | "mime-types": "~2.1.18", 18 | "negotiator": "0.6.1" 19 | } 20 | }, 21 | "ajv": { 22 | "version": "6.5.3", 23 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", 24 | "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", 25 | "requires": { 26 | "fast-deep-equal": "^2.0.1", 27 | "fast-json-stable-stringify": "^2.0.0", 28 | "json-schema-traverse": "^0.4.1", 29 | "uri-js": "^4.2.2" 30 | } 31 | }, 32 | "ansi-align": { 33 | "version": "2.0.0", 34 | "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", 35 | "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", 36 | "requires": { 37 | "string-width": "^2.0.0" 38 | } 39 | }, 40 | "ansi-regex": { 41 | "version": "3.0.0", 42 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 43 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 44 | }, 45 | "ansi-styles": { 46 | "version": "3.2.1", 47 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 48 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 49 | "requires": { 50 | "color-convert": "^1.9.0" 51 | } 52 | }, 53 | "arch": { 54 | "version": "2.1.1", 55 | "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", 56 | "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==" 57 | }, 58 | "arg": { 59 | "version": "2.0.0", 60 | "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz", 61 | "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==" 62 | }, 63 | "balanced-match": { 64 | "version": "1.0.0", 65 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 66 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 67 | }, 68 | "boxen": { 69 | "version": "1.3.0", 70 | "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", 71 | "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", 72 | "requires": { 73 | "ansi-align": "^2.0.0", 74 | "camelcase": "^4.0.0", 75 | "chalk": "^2.0.1", 76 | "cli-boxes": "^1.0.0", 77 | "string-width": "^2.0.0", 78 | "term-size": "^1.2.0", 79 | "widest-line": "^2.0.0" 80 | } 81 | }, 82 | "brace-expansion": { 83 | "version": "1.1.11", 84 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 85 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 86 | "requires": { 87 | "balanced-match": "^1.0.0", 88 | "concat-map": "0.0.1" 89 | } 90 | }, 91 | "bytes": { 92 | "version": "3.0.0", 93 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 94 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 95 | }, 96 | "camelcase": { 97 | "version": "4.1.0", 98 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 99 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" 100 | }, 101 | "chalk": { 102 | "version": "2.4.1", 103 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", 104 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 105 | "requires": { 106 | "ansi-styles": "^3.2.1", 107 | "escape-string-regexp": "^1.0.5", 108 | "supports-color": "^5.3.0" 109 | } 110 | }, 111 | "cli-boxes": { 112 | "version": "1.0.0", 113 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", 114 | "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" 115 | }, 116 | "clipboardy": { 117 | "version": "1.2.3", 118 | "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", 119 | "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", 120 | "requires": { 121 | "arch": "^2.1.0", 122 | "execa": "^0.8.0" 123 | }, 124 | "dependencies": { 125 | "execa": { 126 | "version": "0.8.0", 127 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", 128 | "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", 129 | "requires": { 130 | "cross-spawn": "^5.0.1", 131 | "get-stream": "^3.0.0", 132 | "is-stream": "^1.1.0", 133 | "npm-run-path": "^2.0.0", 134 | "p-finally": "^1.0.0", 135 | "signal-exit": "^3.0.0", 136 | "strip-eof": "^1.0.0" 137 | } 138 | } 139 | } 140 | }, 141 | "color-convert": { 142 | "version": "1.9.3", 143 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 144 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 145 | "requires": { 146 | "color-name": "1.1.3" 147 | } 148 | }, 149 | "color-name": { 150 | "version": "1.1.3", 151 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 152 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 153 | }, 154 | "compressible": { 155 | "version": "2.0.15", 156 | "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", 157 | "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", 158 | "requires": { 159 | "mime-db": ">= 1.36.0 < 2" 160 | } 161 | }, 162 | "compression": { 163 | "version": "1.7.3", 164 | "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", 165 | "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", 166 | "requires": { 167 | "accepts": "~1.3.5", 168 | "bytes": "3.0.0", 169 | "compressible": "~2.0.14", 170 | "debug": "2.6.9", 171 | "on-headers": "~1.0.1", 172 | "safe-buffer": "5.1.2", 173 | "vary": "~1.1.2" 174 | } 175 | }, 176 | "concat-map": { 177 | "version": "0.0.1", 178 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 179 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 180 | }, 181 | "content-disposition": { 182 | "version": "0.5.2", 183 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 184 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 185 | }, 186 | "cross-spawn": { 187 | "version": "5.1.0", 188 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 189 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 190 | "requires": { 191 | "lru-cache": "^4.0.1", 192 | "shebang-command": "^1.2.0", 193 | "which": "^1.2.9" 194 | } 195 | }, 196 | "debug": { 197 | "version": "2.6.9", 198 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 199 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 200 | "requires": { 201 | "ms": "2.0.0" 202 | } 203 | }, 204 | "deep-extend": { 205 | "version": "0.6.0", 206 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 207 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 208 | }, 209 | "escape-string-regexp": { 210 | "version": "1.0.5", 211 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 212 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 213 | }, 214 | "execa": { 215 | "version": "0.7.0", 216 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", 217 | "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", 218 | "requires": { 219 | "cross-spawn": "^5.0.1", 220 | "get-stream": "^3.0.0", 221 | "is-stream": "^1.1.0", 222 | "npm-run-path": "^2.0.0", 223 | "p-finally": "^1.0.0", 224 | "signal-exit": "^3.0.0", 225 | "strip-eof": "^1.0.0" 226 | } 227 | }, 228 | "fast-deep-equal": { 229 | "version": "2.0.1", 230 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 231 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 232 | }, 233 | "fast-json-stable-stringify": { 234 | "version": "2.0.0", 235 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 236 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 237 | }, 238 | "fast-url-parser": { 239 | "version": "1.1.3", 240 | "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", 241 | "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", 242 | "requires": { 243 | "punycode": "^1.3.2" 244 | }, 245 | "dependencies": { 246 | "punycode": { 247 | "version": "1.4.1", 248 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 249 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 250 | } 251 | } 252 | }, 253 | "get-stream": { 254 | "version": "3.0.0", 255 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", 256 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" 257 | }, 258 | "has-flag": { 259 | "version": "3.0.0", 260 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 261 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 262 | }, 263 | "ini": { 264 | "version": "1.3.5", 265 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 266 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 267 | }, 268 | "is-fullwidth-code-point": { 269 | "version": "2.0.0", 270 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 271 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 272 | }, 273 | "is-stream": { 274 | "version": "1.1.0", 275 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 276 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 277 | }, 278 | "isexe": { 279 | "version": "2.0.0", 280 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 281 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 282 | }, 283 | "json-schema-traverse": { 284 | "version": "0.4.1", 285 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 286 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 287 | }, 288 | "lru-cache": { 289 | "version": "4.1.5", 290 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 291 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 292 | "requires": { 293 | "pseudomap": "^1.0.2", 294 | "yallist": "^2.1.2" 295 | } 296 | }, 297 | "mime-db": { 298 | "version": "1.37.0", 299 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", 300 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" 301 | }, 302 | "mime-types": { 303 | "version": "2.1.21", 304 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", 305 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 306 | "requires": { 307 | "mime-db": "~1.37.0" 308 | } 309 | }, 310 | "minimatch": { 311 | "version": "3.0.4", 312 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 313 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 314 | "requires": { 315 | "brace-expansion": "^1.1.7" 316 | } 317 | }, 318 | "minimist": { 319 | "version": "1.2.0", 320 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 321 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 322 | }, 323 | "ms": { 324 | "version": "2.0.0", 325 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 326 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 327 | }, 328 | "negotiator": { 329 | "version": "0.6.1", 330 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 331 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 332 | }, 333 | "npm-run-path": { 334 | "version": "2.0.2", 335 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 336 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 337 | "requires": { 338 | "path-key": "^2.0.0" 339 | } 340 | }, 341 | "on-headers": { 342 | "version": "1.0.1", 343 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", 344 | "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" 345 | }, 346 | "p-finally": { 347 | "version": "1.0.0", 348 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 349 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 350 | }, 351 | "path-is-inside": { 352 | "version": "1.0.2", 353 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 354 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" 355 | }, 356 | "path-key": { 357 | "version": "2.0.1", 358 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 359 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 360 | }, 361 | "path-to-regexp": { 362 | "version": "2.2.1", 363 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", 364 | "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" 365 | }, 366 | "pseudomap": { 367 | "version": "1.0.2", 368 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 369 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 370 | }, 371 | "punycode": { 372 | "version": "2.1.1", 373 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 374 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 375 | }, 376 | "range-parser": { 377 | "version": "1.2.0", 378 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 379 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 380 | }, 381 | "rc": { 382 | "version": "1.2.8", 383 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 384 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 385 | "requires": { 386 | "deep-extend": "^0.6.0", 387 | "ini": "~1.3.0", 388 | "minimist": "^1.2.0", 389 | "strip-json-comments": "~2.0.1" 390 | } 391 | }, 392 | "registry-auth-token": { 393 | "version": "3.3.2", 394 | "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", 395 | "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", 396 | "requires": { 397 | "rc": "^1.1.6", 398 | "safe-buffer": "^5.0.1" 399 | } 400 | }, 401 | "registry-url": { 402 | "version": "3.1.0", 403 | "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", 404 | "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", 405 | "requires": { 406 | "rc": "^1.0.1" 407 | } 408 | }, 409 | "safe-buffer": { 410 | "version": "5.1.2", 411 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 412 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 413 | }, 414 | "serve": { 415 | "version": "10.1.2", 416 | "resolved": "https://registry.npmjs.org/serve/-/serve-10.1.2.tgz", 417 | "integrity": "sha512-TVH35uwndRlCqSeX3grR3Ntrjx2aBTeu6sx+zTD2CzN2N/rHuEDTvxiBwWbrellJNyWiQFz2xZmoW+UxV+Zahg==", 418 | "requires": { 419 | "@zeit/schemas": "2.6.0", 420 | "ajv": "6.5.3", 421 | "arg": "2.0.0", 422 | "boxen": "1.3.0", 423 | "chalk": "2.4.1", 424 | "clipboardy": "1.2.3", 425 | "compression": "1.7.3", 426 | "serve-handler": "5.0.8", 427 | "update-check": "1.5.2" 428 | } 429 | }, 430 | "serve-handler": { 431 | "version": "5.0.8", 432 | "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-5.0.8.tgz", 433 | "integrity": "sha512-pqk0SChbBLLHfMIxQ55czjdiW7tj2cFy53svvP8e5VqEN/uB/QpfiTJ8k1uIYeFTDVoi+FGi5aqXScuu88bymg==", 434 | "requires": { 435 | "bytes": "3.0.0", 436 | "content-disposition": "0.5.2", 437 | "fast-url-parser": "1.1.3", 438 | "mime-types": "2.1.18", 439 | "minimatch": "3.0.4", 440 | "path-is-inside": "1.0.2", 441 | "path-to-regexp": "2.2.1", 442 | "range-parser": "1.2.0" 443 | }, 444 | "dependencies": { 445 | "mime-db": { 446 | "version": "1.33.0", 447 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", 448 | "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" 449 | }, 450 | "mime-types": { 451 | "version": "2.1.18", 452 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", 453 | "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", 454 | "requires": { 455 | "mime-db": "~1.33.0" 456 | } 457 | } 458 | } 459 | }, 460 | "shebang-command": { 461 | "version": "1.2.0", 462 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 463 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 464 | "requires": { 465 | "shebang-regex": "^1.0.0" 466 | } 467 | }, 468 | "shebang-regex": { 469 | "version": "1.0.0", 470 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 471 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" 472 | }, 473 | "signal-exit": { 474 | "version": "3.0.2", 475 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 476 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 477 | }, 478 | "string-width": { 479 | "version": "2.1.1", 480 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 481 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 482 | "requires": { 483 | "is-fullwidth-code-point": "^2.0.0", 484 | "strip-ansi": "^4.0.0" 485 | } 486 | }, 487 | "strip-ansi": { 488 | "version": "4.0.0", 489 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 490 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 491 | "requires": { 492 | "ansi-regex": "^3.0.0" 493 | } 494 | }, 495 | "strip-eof": { 496 | "version": "1.0.0", 497 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 498 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 499 | }, 500 | "strip-json-comments": { 501 | "version": "2.0.1", 502 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 503 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 504 | }, 505 | "supports-color": { 506 | "version": "5.5.0", 507 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 508 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 509 | "requires": { 510 | "has-flag": "^3.0.0" 511 | } 512 | }, 513 | "term-size": { 514 | "version": "1.2.0", 515 | "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", 516 | "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", 517 | "requires": { 518 | "execa": "^0.7.0" 519 | } 520 | }, 521 | "update-check": { 522 | "version": "1.5.2", 523 | "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz", 524 | "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==", 525 | "requires": { 526 | "registry-auth-token": "3.3.2", 527 | "registry-url": "3.1.0" 528 | } 529 | }, 530 | "uri-js": { 531 | "version": "4.2.2", 532 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 533 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 534 | "requires": { 535 | "punycode": "^2.1.0" 536 | } 537 | }, 538 | "vary": { 539 | "version": "1.1.2", 540 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 541 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 542 | }, 543 | "which": { 544 | "version": "1.3.1", 545 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 546 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 547 | "requires": { 548 | "isexe": "^2.0.0" 549 | } 550 | }, 551 | "widest-line": { 552 | "version": "2.0.1", 553 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", 554 | "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", 555 | "requires": { 556 | "string-width": "^2.1.1" 557 | } 558 | }, 559 | "yallist": { 560 | "version": "2.1.2", 561 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 562 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 563 | } 564 | } 565 | } 566 | -------------------------------------------------------------------------------- /demo/simple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple", 3 | "version": "1.0.0", 4 | "license": "MIT", 5 | "dependencies": { 6 | "serve": "^10.1.1" 7 | }, 8 | "scripts": { 9 | "start": "serve" 10 | } 11 | } 12 | --------------------------------------------------------------------------------