├── .eslintrc.yml ├── .gitignore ├── README.md ├── app ├── Dockerfile ├── index.js ├── metrics.js ├── package-lock.json └── package.json ├── docker-compose.yml ├── grafana ├── config.ini ├── dashboards │ └── simple.json └── provisioning │ ├── dashboards │ └── all.yml │ └── datasources │ └── all.yml └── prometheus └── prometheus.yml /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | commonjs: true 3 | es6: true 4 | node: true 5 | extends: 'eslint:recommended' 6 | globals: 7 | Atomics: readonly 8 | SharedArrayBuffer: readonly 9 | parserOptions: 10 | ecmaVersion: 2018 11 | rules: {} 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /app/node_modules 2 | .idea/ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Visualizing metrics from the Node JS application with Prometheus and Grafana 2 | 3 | ## Run 4 | 5 | ```bash 6 | docker-compose up -d 7 | ``` 8 | 9 | Then open the http://localhost:3000, login (admin:illchangeitanyway) and check out the results! 10 | 11 | Full tutorial you can find in my blog - [https://sergeypotekhin.com/](http://sergeypotekhin.com/visualizing-data-from-the-node-js-app/?utm_source=github&utm_medium=readme&utm_campaign=repos). 12 | 13 | See ya! 14 | -------------------------------------------------------------------------------- /app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | 3 | WORKDIR /app 4 | 5 | RUN \ 6 | set -eux; \ 7 | apt-get update && \ 8 | apt-get install -y curl build-essential python git && \ 9 | curl -sL https://deb.nodesource.com/setup_12.x | bash - && \ 10 | apt-get install -y nodejs 11 | 12 | COPY . . 13 | 14 | RUN npm install --unsafe-perm 15 | 16 | ENTRYPOINT ["node"] 17 | 18 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | const client = require('prom-client'); 2 | const express = require('express'); 3 | 4 | const metricExporter = require('./metrics'); 5 | 6 | const app = express(); 7 | 8 | // Initialize metrics 9 | const registry = new client.Registry(); 10 | metricExporter(registry); 11 | 12 | // Report Prometheus metrics on /metrics 13 | app.get('/metrics', async (req, res, next) => { 14 | res.set('Content-Type', registry.contentType); 15 | res.end(registry.metrics()); 16 | 17 | next(); 18 | }); 19 | 20 | 21 | // Run the server 22 | app.listen(9200, '0.0.0.0', () => console.log('App started!')); 23 | -------------------------------------------------------------------------------- /app/metrics.js: -------------------------------------------------------------------------------- 1 | const client = require('prom-client'); 2 | const gaussian = require('gaussian'); 3 | 4 | 5 | function activeUsersPerCategoryMetric(registry) { 6 | const gauge = new client.Gauge({ 7 | name: 'active_users', 8 | help: 'Amount of active users right now per category', 9 | registers: [registry], 10 | labelNames: [ 11 | 'category', 12 | ], 13 | }); 14 | 15 | // To make data looks more 16 | const categoriesWithDistribution = [ 17 | ['oil', 100, 30], 18 | ['wine', 200, 30], 19 | ['bread', 300, 30], 20 | ['butter', 400, 30], 21 | ]; 22 | 23 | async function collectActiveUsers() { 24 | categoriesWithDistribution.map(async ([category, mean, variance]) => { 25 | gauge.set( 26 | { category }, 27 | Math.floor(gaussian(mean, variance).ppf(Math.random())), 28 | ); 29 | }); 30 | } 31 | 32 | setInterval(collectActiveUsers, 5000); 33 | } 34 | 35 | 36 | module.exports = (registry) => { 37 | activeUsersPerCategoryMetric(registry); 38 | }; 39 | -------------------------------------------------------------------------------- /app/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grafana-prometheus-node-js-example-app", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.8.3", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", 10 | "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.8.3" 14 | } 15 | }, 16 | "@babel/highlight": { 17 | "version": "7.8.3", 18 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", 19 | "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", 20 | "dev": true, 21 | "requires": { 22 | "chalk": "^2.0.0", 23 | "esutils": "^2.0.2", 24 | "js-tokens": "^4.0.0" 25 | } 26 | }, 27 | "accepts": { 28 | "version": "1.3.7", 29 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 30 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 31 | "requires": { 32 | "mime-types": "~2.1.24", 33 | "negotiator": "0.6.2" 34 | } 35 | }, 36 | "acorn": { 37 | "version": "7.1.0", 38 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", 39 | "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", 40 | "dev": true 41 | }, 42 | "acorn-jsx": { 43 | "version": "5.1.0", 44 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", 45 | "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", 46 | "dev": true 47 | }, 48 | "ajv": { 49 | "version": "6.11.0", 50 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", 51 | "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", 52 | "dev": true, 53 | "requires": { 54 | "fast-deep-equal": "^3.1.1", 55 | "fast-json-stable-stringify": "^2.0.0", 56 | "json-schema-traverse": "^0.4.1", 57 | "uri-js": "^4.2.2" 58 | } 59 | }, 60 | "ansi-escapes": { 61 | "version": "4.3.0", 62 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", 63 | "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", 64 | "dev": true, 65 | "requires": { 66 | "type-fest": "^0.8.1" 67 | } 68 | }, 69 | "ansi-regex": { 70 | "version": "5.0.0", 71 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 72 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 73 | "dev": true 74 | }, 75 | "ansi-styles": { 76 | "version": "3.2.1", 77 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 78 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 79 | "dev": true, 80 | "requires": { 81 | "color-convert": "^1.9.0" 82 | } 83 | }, 84 | "argparse": { 85 | "version": "1.0.10", 86 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 87 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 88 | "dev": true, 89 | "requires": { 90 | "sprintf-js": "~1.0.2" 91 | } 92 | }, 93 | "array-flatten": { 94 | "version": "1.1.1", 95 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 96 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 97 | }, 98 | "astral-regex": { 99 | "version": "1.0.0", 100 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 101 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 102 | "dev": true 103 | }, 104 | "balanced-match": { 105 | "version": "1.0.0", 106 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 107 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 108 | "dev": true 109 | }, 110 | "bintrees": { 111 | "version": "1.0.1", 112 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", 113 | "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" 114 | }, 115 | "body-parser": { 116 | "version": "1.19.0", 117 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 118 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 119 | "requires": { 120 | "bytes": "3.1.0", 121 | "content-type": "~1.0.4", 122 | "debug": "2.6.9", 123 | "depd": "~1.1.2", 124 | "http-errors": "1.7.2", 125 | "iconv-lite": "0.4.24", 126 | "on-finished": "~2.3.0", 127 | "qs": "6.7.0", 128 | "raw-body": "2.4.0", 129 | "type-is": "~1.6.17" 130 | } 131 | }, 132 | "brace-expansion": { 133 | "version": "1.1.11", 134 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 135 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 136 | "dev": true, 137 | "requires": { 138 | "balanced-match": "^1.0.0", 139 | "concat-map": "0.0.1" 140 | } 141 | }, 142 | "bytes": { 143 | "version": "3.1.0", 144 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 145 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 146 | }, 147 | "callsites": { 148 | "version": "3.1.0", 149 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 150 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 151 | "dev": true 152 | }, 153 | "chalk": { 154 | "version": "2.4.2", 155 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 156 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 157 | "dev": true, 158 | "requires": { 159 | "ansi-styles": "^3.2.1", 160 | "escape-string-regexp": "^1.0.5", 161 | "supports-color": "^5.3.0" 162 | } 163 | }, 164 | "chardet": { 165 | "version": "0.7.0", 166 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 167 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 168 | "dev": true 169 | }, 170 | "cli-cursor": { 171 | "version": "3.1.0", 172 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", 173 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", 174 | "dev": true, 175 | "requires": { 176 | "restore-cursor": "^3.1.0" 177 | } 178 | }, 179 | "cli-width": { 180 | "version": "2.2.0", 181 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 182 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 183 | "dev": true 184 | }, 185 | "color-convert": { 186 | "version": "1.9.3", 187 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 188 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 189 | "dev": true, 190 | "requires": { 191 | "color-name": "1.1.3" 192 | } 193 | }, 194 | "color-name": { 195 | "version": "1.1.3", 196 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 197 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 198 | "dev": true 199 | }, 200 | "concat-map": { 201 | "version": "0.0.1", 202 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 203 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 204 | "dev": true 205 | }, 206 | "content-disposition": { 207 | "version": "0.5.3", 208 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 209 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 210 | "requires": { 211 | "safe-buffer": "5.1.2" 212 | } 213 | }, 214 | "content-type": { 215 | "version": "1.0.4", 216 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 217 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 218 | }, 219 | "cookie": { 220 | "version": "0.4.0", 221 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 222 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 223 | }, 224 | "cookie-signature": { 225 | "version": "1.0.6", 226 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 227 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 228 | }, 229 | "cross-spawn": { 230 | "version": "6.0.5", 231 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 232 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 233 | "dev": true, 234 | "requires": { 235 | "nice-try": "^1.0.4", 236 | "path-key": "^2.0.1", 237 | "semver": "^5.5.0", 238 | "shebang-command": "^1.2.0", 239 | "which": "^1.2.9" 240 | }, 241 | "dependencies": { 242 | "semver": { 243 | "version": "5.7.1", 244 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 245 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 246 | "dev": true 247 | } 248 | } 249 | }, 250 | "debug": { 251 | "version": "2.6.9", 252 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 253 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 254 | "requires": { 255 | "ms": "2.0.0" 256 | } 257 | }, 258 | "deep-is": { 259 | "version": "0.1.3", 260 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 261 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 262 | "dev": true 263 | }, 264 | "depd": { 265 | "version": "1.1.2", 266 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 267 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 268 | }, 269 | "destroy": { 270 | "version": "1.0.4", 271 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 272 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 273 | }, 274 | "doctrine": { 275 | "version": "3.0.0", 276 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 277 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 278 | "dev": true, 279 | "requires": { 280 | "esutils": "^2.0.2" 281 | } 282 | }, 283 | "ee-first": { 284 | "version": "1.1.1", 285 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 286 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 287 | }, 288 | "emoji-regex": { 289 | "version": "8.0.0", 290 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 291 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 292 | "dev": true 293 | }, 294 | "encodeurl": { 295 | "version": "1.0.2", 296 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 297 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 298 | }, 299 | "escape-html": { 300 | "version": "1.0.3", 301 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 302 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 303 | }, 304 | "escape-string-regexp": { 305 | "version": "1.0.5", 306 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 307 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 308 | "dev": true 309 | }, 310 | "eslint": { 311 | "version": "6.8.0", 312 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", 313 | "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", 314 | "dev": true, 315 | "requires": { 316 | "@babel/code-frame": "^7.0.0", 317 | "ajv": "^6.10.0", 318 | "chalk": "^2.1.0", 319 | "cross-spawn": "^6.0.5", 320 | "debug": "^4.0.1", 321 | "doctrine": "^3.0.0", 322 | "eslint-scope": "^5.0.0", 323 | "eslint-utils": "^1.4.3", 324 | "eslint-visitor-keys": "^1.1.0", 325 | "espree": "^6.1.2", 326 | "esquery": "^1.0.1", 327 | "esutils": "^2.0.2", 328 | "file-entry-cache": "^5.0.1", 329 | "functional-red-black-tree": "^1.0.1", 330 | "glob-parent": "^5.0.0", 331 | "globals": "^12.1.0", 332 | "ignore": "^4.0.6", 333 | "import-fresh": "^3.0.0", 334 | "imurmurhash": "^0.1.4", 335 | "inquirer": "^7.0.0", 336 | "is-glob": "^4.0.0", 337 | "js-yaml": "^3.13.1", 338 | "json-stable-stringify-without-jsonify": "^1.0.1", 339 | "levn": "^0.3.0", 340 | "lodash": "^4.17.14", 341 | "minimatch": "^3.0.4", 342 | "mkdirp": "^0.5.1", 343 | "natural-compare": "^1.4.0", 344 | "optionator": "^0.8.3", 345 | "progress": "^2.0.0", 346 | "regexpp": "^2.0.1", 347 | "semver": "^6.1.2", 348 | "strip-ansi": "^5.2.0", 349 | "strip-json-comments": "^3.0.1", 350 | "table": "^5.2.3", 351 | "text-table": "^0.2.0", 352 | "v8-compile-cache": "^2.0.3" 353 | }, 354 | "dependencies": { 355 | "debug": { 356 | "version": "4.1.1", 357 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 358 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 359 | "dev": true, 360 | "requires": { 361 | "ms": "^2.1.1" 362 | } 363 | }, 364 | "ms": { 365 | "version": "2.1.2", 366 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 367 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 368 | "dev": true 369 | } 370 | } 371 | }, 372 | "eslint-scope": { 373 | "version": "5.0.0", 374 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", 375 | "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", 376 | "dev": true, 377 | "requires": { 378 | "esrecurse": "^4.1.0", 379 | "estraverse": "^4.1.1" 380 | } 381 | }, 382 | "eslint-utils": { 383 | "version": "1.4.3", 384 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 385 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 386 | "dev": true, 387 | "requires": { 388 | "eslint-visitor-keys": "^1.1.0" 389 | } 390 | }, 391 | "eslint-visitor-keys": { 392 | "version": "1.1.0", 393 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", 394 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", 395 | "dev": true 396 | }, 397 | "espree": { 398 | "version": "6.1.2", 399 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", 400 | "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", 401 | "dev": true, 402 | "requires": { 403 | "acorn": "^7.1.0", 404 | "acorn-jsx": "^5.1.0", 405 | "eslint-visitor-keys": "^1.1.0" 406 | } 407 | }, 408 | "esprima": { 409 | "version": "4.0.1", 410 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 411 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 412 | "dev": true 413 | }, 414 | "esquery": { 415 | "version": "1.1.0", 416 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", 417 | "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", 418 | "dev": true, 419 | "requires": { 420 | "estraverse": "^4.0.0" 421 | } 422 | }, 423 | "esrecurse": { 424 | "version": "4.2.1", 425 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 426 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 427 | "dev": true, 428 | "requires": { 429 | "estraverse": "^4.1.0" 430 | } 431 | }, 432 | "estraverse": { 433 | "version": "4.3.0", 434 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 435 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 436 | "dev": true 437 | }, 438 | "esutils": { 439 | "version": "2.0.3", 440 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 441 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 442 | "dev": true 443 | }, 444 | "etag": { 445 | "version": "1.8.1", 446 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 447 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 448 | }, 449 | "express": { 450 | "version": "4.17.1", 451 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 452 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 453 | "requires": { 454 | "accepts": "~1.3.7", 455 | "array-flatten": "1.1.1", 456 | "body-parser": "1.19.0", 457 | "content-disposition": "0.5.3", 458 | "content-type": "~1.0.4", 459 | "cookie": "0.4.0", 460 | "cookie-signature": "1.0.6", 461 | "debug": "2.6.9", 462 | "depd": "~1.1.2", 463 | "encodeurl": "~1.0.2", 464 | "escape-html": "~1.0.3", 465 | "etag": "~1.8.1", 466 | "finalhandler": "~1.1.2", 467 | "fresh": "0.5.2", 468 | "merge-descriptors": "1.0.1", 469 | "methods": "~1.1.2", 470 | "on-finished": "~2.3.0", 471 | "parseurl": "~1.3.3", 472 | "path-to-regexp": "0.1.7", 473 | "proxy-addr": "~2.0.5", 474 | "qs": "6.7.0", 475 | "range-parser": "~1.2.1", 476 | "safe-buffer": "5.1.2", 477 | "send": "0.17.1", 478 | "serve-static": "1.14.1", 479 | "setprototypeof": "1.1.1", 480 | "statuses": "~1.5.0", 481 | "type-is": "~1.6.18", 482 | "utils-merge": "1.0.1", 483 | "vary": "~1.1.2" 484 | } 485 | }, 486 | "external-editor": { 487 | "version": "3.1.0", 488 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 489 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 490 | "dev": true, 491 | "requires": { 492 | "chardet": "^0.7.0", 493 | "iconv-lite": "^0.4.24", 494 | "tmp": "^0.0.33" 495 | } 496 | }, 497 | "fast-deep-equal": { 498 | "version": "3.1.1", 499 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", 500 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", 501 | "dev": true 502 | }, 503 | "fast-json-stable-stringify": { 504 | "version": "2.1.0", 505 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 506 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 507 | "dev": true 508 | }, 509 | "fast-levenshtein": { 510 | "version": "2.0.6", 511 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 512 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 513 | "dev": true 514 | }, 515 | "figures": { 516 | "version": "3.1.0", 517 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", 518 | "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", 519 | "dev": true, 520 | "requires": { 521 | "escape-string-regexp": "^1.0.5" 522 | } 523 | }, 524 | "file-entry-cache": { 525 | "version": "5.0.1", 526 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 527 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 528 | "dev": true, 529 | "requires": { 530 | "flat-cache": "^2.0.1" 531 | } 532 | }, 533 | "finalhandler": { 534 | "version": "1.1.2", 535 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 536 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 537 | "requires": { 538 | "debug": "2.6.9", 539 | "encodeurl": "~1.0.2", 540 | "escape-html": "~1.0.3", 541 | "on-finished": "~2.3.0", 542 | "parseurl": "~1.3.3", 543 | "statuses": "~1.5.0", 544 | "unpipe": "~1.0.0" 545 | } 546 | }, 547 | "flat-cache": { 548 | "version": "2.0.1", 549 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 550 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 551 | "dev": true, 552 | "requires": { 553 | "flatted": "^2.0.0", 554 | "rimraf": "2.6.3", 555 | "write": "1.0.3" 556 | } 557 | }, 558 | "flatted": { 559 | "version": "2.0.1", 560 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 561 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 562 | "dev": true 563 | }, 564 | "forwarded": { 565 | "version": "0.1.2", 566 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 567 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 568 | }, 569 | "fresh": { 570 | "version": "0.5.2", 571 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 572 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 573 | }, 574 | "fs.realpath": { 575 | "version": "1.0.0", 576 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 577 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 578 | "dev": true 579 | }, 580 | "functional-red-black-tree": { 581 | "version": "1.0.1", 582 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 583 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 584 | "dev": true 585 | }, 586 | "gaussian": { 587 | "version": "1.1.0", 588 | "resolved": "https://registry.npmjs.org/gaussian/-/gaussian-1.1.0.tgz", 589 | "integrity": "sha1-bRN6CX1Nv8ILUvsctdYcRwDt13E=" 590 | }, 591 | "glob": { 592 | "version": "7.1.6", 593 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 594 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 595 | "dev": true, 596 | "requires": { 597 | "fs.realpath": "^1.0.0", 598 | "inflight": "^1.0.4", 599 | "inherits": "2", 600 | "minimatch": "^3.0.4", 601 | "once": "^1.3.0", 602 | "path-is-absolute": "^1.0.0" 603 | } 604 | }, 605 | "glob-parent": { 606 | "version": "5.1.0", 607 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", 608 | "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", 609 | "dev": true, 610 | "requires": { 611 | "is-glob": "^4.0.1" 612 | } 613 | }, 614 | "globals": { 615 | "version": "12.3.0", 616 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", 617 | "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", 618 | "dev": true, 619 | "requires": { 620 | "type-fest": "^0.8.1" 621 | } 622 | }, 623 | "has-flag": { 624 | "version": "3.0.0", 625 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 626 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 627 | "dev": true 628 | }, 629 | "http-errors": { 630 | "version": "1.7.2", 631 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 632 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 633 | "requires": { 634 | "depd": "~1.1.2", 635 | "inherits": "2.0.3", 636 | "setprototypeof": "1.1.1", 637 | "statuses": ">= 1.5.0 < 2", 638 | "toidentifier": "1.0.0" 639 | } 640 | }, 641 | "iconv-lite": { 642 | "version": "0.4.24", 643 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 644 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 645 | "requires": { 646 | "safer-buffer": ">= 2.1.2 < 3" 647 | } 648 | }, 649 | "ignore": { 650 | "version": "4.0.6", 651 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 652 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 653 | "dev": true 654 | }, 655 | "import-fresh": { 656 | "version": "3.2.1", 657 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 658 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 659 | "dev": true, 660 | "requires": { 661 | "parent-module": "^1.0.0", 662 | "resolve-from": "^4.0.0" 663 | } 664 | }, 665 | "imurmurhash": { 666 | "version": "0.1.4", 667 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 668 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 669 | "dev": true 670 | }, 671 | "inflight": { 672 | "version": "1.0.6", 673 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 674 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 675 | "dev": true, 676 | "requires": { 677 | "once": "^1.3.0", 678 | "wrappy": "1" 679 | } 680 | }, 681 | "inherits": { 682 | "version": "2.0.3", 683 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 684 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 685 | }, 686 | "inquirer": { 687 | "version": "7.0.4", 688 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", 689 | "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", 690 | "dev": true, 691 | "requires": { 692 | "ansi-escapes": "^4.2.1", 693 | "chalk": "^2.4.2", 694 | "cli-cursor": "^3.1.0", 695 | "cli-width": "^2.0.0", 696 | "external-editor": "^3.0.3", 697 | "figures": "^3.0.0", 698 | "lodash": "^4.17.15", 699 | "mute-stream": "0.0.8", 700 | "run-async": "^2.2.0", 701 | "rxjs": "^6.5.3", 702 | "string-width": "^4.1.0", 703 | "strip-ansi": "^5.1.0", 704 | "through": "^2.3.6" 705 | } 706 | }, 707 | "ipaddr.js": { 708 | "version": "1.9.0", 709 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", 710 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" 711 | }, 712 | "is-extglob": { 713 | "version": "2.1.1", 714 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 715 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 716 | "dev": true 717 | }, 718 | "is-fullwidth-code-point": { 719 | "version": "3.0.0", 720 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 721 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 722 | "dev": true 723 | }, 724 | "is-glob": { 725 | "version": "4.0.1", 726 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 727 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 728 | "dev": true, 729 | "requires": { 730 | "is-extglob": "^2.1.1" 731 | } 732 | }, 733 | "is-promise": { 734 | "version": "2.1.0", 735 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 736 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 737 | "dev": true 738 | }, 739 | "isexe": { 740 | "version": "2.0.0", 741 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 742 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 743 | "dev": true 744 | }, 745 | "js-tokens": { 746 | "version": "4.0.0", 747 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 748 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 749 | "dev": true 750 | }, 751 | "js-yaml": { 752 | "version": "3.13.1", 753 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 754 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 755 | "dev": true, 756 | "requires": { 757 | "argparse": "^1.0.7", 758 | "esprima": "^4.0.0" 759 | } 760 | }, 761 | "json-schema-traverse": { 762 | "version": "0.4.1", 763 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 764 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 765 | "dev": true 766 | }, 767 | "json-stable-stringify-without-jsonify": { 768 | "version": "1.0.1", 769 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 770 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 771 | "dev": true 772 | }, 773 | "levn": { 774 | "version": "0.3.0", 775 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 776 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 777 | "dev": true, 778 | "requires": { 779 | "prelude-ls": "~1.1.2", 780 | "type-check": "~0.3.2" 781 | } 782 | }, 783 | "lodash": { 784 | "version": "4.17.15", 785 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 786 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 787 | "dev": true 788 | }, 789 | "media-typer": { 790 | "version": "0.3.0", 791 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 792 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 793 | }, 794 | "merge-descriptors": { 795 | "version": "1.0.1", 796 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 797 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 798 | }, 799 | "methods": { 800 | "version": "1.1.2", 801 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 802 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 803 | }, 804 | "mime": { 805 | "version": "1.6.0", 806 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 807 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 808 | }, 809 | "mime-db": { 810 | "version": "1.43.0", 811 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", 812 | "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" 813 | }, 814 | "mime-types": { 815 | "version": "2.1.26", 816 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", 817 | "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", 818 | "requires": { 819 | "mime-db": "1.43.0" 820 | } 821 | }, 822 | "mimic-fn": { 823 | "version": "2.1.0", 824 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 825 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 826 | "dev": true 827 | }, 828 | "minimatch": { 829 | "version": "3.0.4", 830 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 831 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 832 | "dev": true, 833 | "requires": { 834 | "brace-expansion": "^1.1.7" 835 | } 836 | }, 837 | "minimist": { 838 | "version": "0.0.8", 839 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 840 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 841 | "dev": true 842 | }, 843 | "mkdirp": { 844 | "version": "0.5.1", 845 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 846 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 847 | "dev": true, 848 | "requires": { 849 | "minimist": "0.0.8" 850 | } 851 | }, 852 | "ms": { 853 | "version": "2.0.0", 854 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 855 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 856 | }, 857 | "mute-stream": { 858 | "version": "0.0.8", 859 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", 860 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", 861 | "dev": true 862 | }, 863 | "natural-compare": { 864 | "version": "1.4.0", 865 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 866 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 867 | "dev": true 868 | }, 869 | "negotiator": { 870 | "version": "0.6.2", 871 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 872 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 873 | }, 874 | "nice-try": { 875 | "version": "1.0.5", 876 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 877 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 878 | "dev": true 879 | }, 880 | "on-finished": { 881 | "version": "2.3.0", 882 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 883 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 884 | "requires": { 885 | "ee-first": "1.1.1" 886 | } 887 | }, 888 | "once": { 889 | "version": "1.4.0", 890 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 891 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 892 | "dev": true, 893 | "requires": { 894 | "wrappy": "1" 895 | } 896 | }, 897 | "onetime": { 898 | "version": "5.1.0", 899 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", 900 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", 901 | "dev": true, 902 | "requires": { 903 | "mimic-fn": "^2.1.0" 904 | } 905 | }, 906 | "optionator": { 907 | "version": "0.8.3", 908 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 909 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 910 | "dev": true, 911 | "requires": { 912 | "deep-is": "~0.1.3", 913 | "fast-levenshtein": "~2.0.6", 914 | "levn": "~0.3.0", 915 | "prelude-ls": "~1.1.2", 916 | "type-check": "~0.3.2", 917 | "word-wrap": "~1.2.3" 918 | } 919 | }, 920 | "os-tmpdir": { 921 | "version": "1.0.2", 922 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 923 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 924 | "dev": true 925 | }, 926 | "parent-module": { 927 | "version": "1.0.1", 928 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 929 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 930 | "dev": true, 931 | "requires": { 932 | "callsites": "^3.0.0" 933 | } 934 | }, 935 | "parseurl": { 936 | "version": "1.3.3", 937 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 938 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 939 | }, 940 | "path-is-absolute": { 941 | "version": "1.0.1", 942 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 943 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 944 | "dev": true 945 | }, 946 | "path-key": { 947 | "version": "2.0.1", 948 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 949 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 950 | "dev": true 951 | }, 952 | "path-to-regexp": { 953 | "version": "0.1.7", 954 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 955 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 956 | }, 957 | "prelude-ls": { 958 | "version": "1.1.2", 959 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 960 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 961 | "dev": true 962 | }, 963 | "progress": { 964 | "version": "2.0.3", 965 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 966 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 967 | "dev": true 968 | }, 969 | "prom-client": { 970 | "version": "11.5.3", 971 | "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.3.tgz", 972 | "integrity": "sha512-iz22FmTbtkyL2vt0MdDFY+kWof+S9UB/NACxSn2aJcewtw+EERsen0urSkZ2WrHseNdydsvcxCTAnPcSMZZv4Q==", 973 | "requires": { 974 | "tdigest": "^0.1.1" 975 | } 976 | }, 977 | "proxy-addr": { 978 | "version": "2.0.5", 979 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", 980 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", 981 | "requires": { 982 | "forwarded": "~0.1.2", 983 | "ipaddr.js": "1.9.0" 984 | } 985 | }, 986 | "punycode": { 987 | "version": "2.1.1", 988 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 989 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 990 | "dev": true 991 | }, 992 | "qs": { 993 | "version": "6.7.0", 994 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 995 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 996 | }, 997 | "range-parser": { 998 | "version": "1.2.1", 999 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1000 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1001 | }, 1002 | "raw-body": { 1003 | "version": "2.4.0", 1004 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 1005 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 1006 | "requires": { 1007 | "bytes": "3.1.0", 1008 | "http-errors": "1.7.2", 1009 | "iconv-lite": "0.4.24", 1010 | "unpipe": "1.0.0" 1011 | } 1012 | }, 1013 | "regexpp": { 1014 | "version": "2.0.1", 1015 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 1016 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 1017 | "dev": true 1018 | }, 1019 | "resolve-from": { 1020 | "version": "4.0.0", 1021 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1022 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1023 | "dev": true 1024 | }, 1025 | "restore-cursor": { 1026 | "version": "3.1.0", 1027 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", 1028 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", 1029 | "dev": true, 1030 | "requires": { 1031 | "onetime": "^5.1.0", 1032 | "signal-exit": "^3.0.2" 1033 | } 1034 | }, 1035 | "rimraf": { 1036 | "version": "2.6.3", 1037 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1038 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1039 | "dev": true, 1040 | "requires": { 1041 | "glob": "^7.1.3" 1042 | } 1043 | }, 1044 | "run-async": { 1045 | "version": "2.3.0", 1046 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 1047 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 1048 | "dev": true, 1049 | "requires": { 1050 | "is-promise": "^2.1.0" 1051 | } 1052 | }, 1053 | "rxjs": { 1054 | "version": "6.5.4", 1055 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", 1056 | "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", 1057 | "dev": true, 1058 | "requires": { 1059 | "tslib": "^1.9.0" 1060 | } 1061 | }, 1062 | "safe-buffer": { 1063 | "version": "5.1.2", 1064 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1065 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1066 | }, 1067 | "safer-buffer": { 1068 | "version": "2.1.2", 1069 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1070 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1071 | }, 1072 | "semver": { 1073 | "version": "6.3.0", 1074 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1075 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1076 | "dev": true 1077 | }, 1078 | "send": { 1079 | "version": "0.17.1", 1080 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 1081 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 1082 | "requires": { 1083 | "debug": "2.6.9", 1084 | "depd": "~1.1.2", 1085 | "destroy": "~1.0.4", 1086 | "encodeurl": "~1.0.2", 1087 | "escape-html": "~1.0.3", 1088 | "etag": "~1.8.1", 1089 | "fresh": "0.5.2", 1090 | "http-errors": "~1.7.2", 1091 | "mime": "1.6.0", 1092 | "ms": "2.1.1", 1093 | "on-finished": "~2.3.0", 1094 | "range-parser": "~1.2.1", 1095 | "statuses": "~1.5.0" 1096 | }, 1097 | "dependencies": { 1098 | "ms": { 1099 | "version": "2.1.1", 1100 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1101 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1102 | } 1103 | } 1104 | }, 1105 | "serve-static": { 1106 | "version": "1.14.1", 1107 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 1108 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 1109 | "requires": { 1110 | "encodeurl": "~1.0.2", 1111 | "escape-html": "~1.0.3", 1112 | "parseurl": "~1.3.3", 1113 | "send": "0.17.1" 1114 | } 1115 | }, 1116 | "setprototypeof": { 1117 | "version": "1.1.1", 1118 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 1119 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 1120 | }, 1121 | "shebang-command": { 1122 | "version": "1.2.0", 1123 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1124 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1125 | "dev": true, 1126 | "requires": { 1127 | "shebang-regex": "^1.0.0" 1128 | } 1129 | }, 1130 | "shebang-regex": { 1131 | "version": "1.0.0", 1132 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1133 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 1134 | "dev": true 1135 | }, 1136 | "signal-exit": { 1137 | "version": "3.0.2", 1138 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1139 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 1140 | "dev": true 1141 | }, 1142 | "slice-ansi": { 1143 | "version": "2.1.0", 1144 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1145 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1146 | "dev": true, 1147 | "requires": { 1148 | "ansi-styles": "^3.2.0", 1149 | "astral-regex": "^1.0.0", 1150 | "is-fullwidth-code-point": "^2.0.0" 1151 | }, 1152 | "dependencies": { 1153 | "is-fullwidth-code-point": { 1154 | "version": "2.0.0", 1155 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1156 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1157 | "dev": true 1158 | } 1159 | } 1160 | }, 1161 | "sprintf-js": { 1162 | "version": "1.0.3", 1163 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1164 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1165 | "dev": true 1166 | }, 1167 | "statuses": { 1168 | "version": "1.5.0", 1169 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1170 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1171 | }, 1172 | "string-width": { 1173 | "version": "4.2.0", 1174 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 1175 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 1176 | "dev": true, 1177 | "requires": { 1178 | "emoji-regex": "^8.0.0", 1179 | "is-fullwidth-code-point": "^3.0.0", 1180 | "strip-ansi": "^6.0.0" 1181 | }, 1182 | "dependencies": { 1183 | "strip-ansi": { 1184 | "version": "6.0.0", 1185 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1186 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1187 | "dev": true, 1188 | "requires": { 1189 | "ansi-regex": "^5.0.0" 1190 | } 1191 | } 1192 | } 1193 | }, 1194 | "strip-ansi": { 1195 | "version": "5.2.0", 1196 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1197 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1198 | "dev": true, 1199 | "requires": { 1200 | "ansi-regex": "^4.1.0" 1201 | }, 1202 | "dependencies": { 1203 | "ansi-regex": { 1204 | "version": "4.1.0", 1205 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1206 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1207 | "dev": true 1208 | } 1209 | } 1210 | }, 1211 | "strip-json-comments": { 1212 | "version": "3.0.1", 1213 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 1214 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 1215 | "dev": true 1216 | }, 1217 | "supports-color": { 1218 | "version": "5.5.0", 1219 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1220 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1221 | "dev": true, 1222 | "requires": { 1223 | "has-flag": "^3.0.0" 1224 | } 1225 | }, 1226 | "table": { 1227 | "version": "5.4.6", 1228 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 1229 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 1230 | "dev": true, 1231 | "requires": { 1232 | "ajv": "^6.10.2", 1233 | "lodash": "^4.17.14", 1234 | "slice-ansi": "^2.1.0", 1235 | "string-width": "^3.0.0" 1236 | }, 1237 | "dependencies": { 1238 | "emoji-regex": { 1239 | "version": "7.0.3", 1240 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 1241 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 1242 | "dev": true 1243 | }, 1244 | "is-fullwidth-code-point": { 1245 | "version": "2.0.0", 1246 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1247 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1248 | "dev": true 1249 | }, 1250 | "string-width": { 1251 | "version": "3.1.0", 1252 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1253 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1254 | "dev": true, 1255 | "requires": { 1256 | "emoji-regex": "^7.0.1", 1257 | "is-fullwidth-code-point": "^2.0.0", 1258 | "strip-ansi": "^5.1.0" 1259 | } 1260 | } 1261 | } 1262 | }, 1263 | "tdigest": { 1264 | "version": "0.1.1", 1265 | "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", 1266 | "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", 1267 | "requires": { 1268 | "bintrees": "1.0.1" 1269 | } 1270 | }, 1271 | "text-table": { 1272 | "version": "0.2.0", 1273 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1274 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1275 | "dev": true 1276 | }, 1277 | "through": { 1278 | "version": "2.3.8", 1279 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1280 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 1281 | "dev": true 1282 | }, 1283 | "tmp": { 1284 | "version": "0.0.33", 1285 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1286 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1287 | "dev": true, 1288 | "requires": { 1289 | "os-tmpdir": "~1.0.2" 1290 | } 1291 | }, 1292 | "toidentifier": { 1293 | "version": "1.0.0", 1294 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 1295 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 1296 | }, 1297 | "tslib": { 1298 | "version": "1.10.0", 1299 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 1300 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", 1301 | "dev": true 1302 | }, 1303 | "type-check": { 1304 | "version": "0.3.2", 1305 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1306 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1307 | "dev": true, 1308 | "requires": { 1309 | "prelude-ls": "~1.1.2" 1310 | } 1311 | }, 1312 | "type-fest": { 1313 | "version": "0.8.1", 1314 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 1315 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 1316 | "dev": true 1317 | }, 1318 | "type-is": { 1319 | "version": "1.6.18", 1320 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1321 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1322 | "requires": { 1323 | "media-typer": "0.3.0", 1324 | "mime-types": "~2.1.24" 1325 | } 1326 | }, 1327 | "unpipe": { 1328 | "version": "1.0.0", 1329 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1330 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1331 | }, 1332 | "uri-js": { 1333 | "version": "4.2.2", 1334 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1335 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1336 | "dev": true, 1337 | "requires": { 1338 | "punycode": "^2.1.0" 1339 | } 1340 | }, 1341 | "utils-merge": { 1342 | "version": "1.0.1", 1343 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1344 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1345 | }, 1346 | "v8-compile-cache": { 1347 | "version": "2.1.0", 1348 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", 1349 | "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", 1350 | "dev": true 1351 | }, 1352 | "vary": { 1353 | "version": "1.1.2", 1354 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1355 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1356 | }, 1357 | "which": { 1358 | "version": "1.3.1", 1359 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1360 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1361 | "dev": true, 1362 | "requires": { 1363 | "isexe": "^2.0.0" 1364 | } 1365 | }, 1366 | "word-wrap": { 1367 | "version": "1.2.3", 1368 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1369 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1370 | "dev": true 1371 | }, 1372 | "wrappy": { 1373 | "version": "1.0.2", 1374 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1375 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1376 | "dev": true 1377 | }, 1378 | "write": { 1379 | "version": "1.0.3", 1380 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 1381 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 1382 | "dev": true, 1383 | "requires": { 1384 | "mkdirp": "^0.5.1" 1385 | } 1386 | } 1387 | } 1388 | } 1389 | -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grafana-prometheus-node-js-example-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "pavlovdog_ ", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.17.1", 13 | "gaussian": "^1.1.0", 14 | "prom-client": "^11.5.3" 15 | }, 16 | "devDependencies": { 17 | "eslint": "^6.8.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # docker-compose.yml 2 | version: '2' 3 | services: 4 | prometheus: 5 | image: prom/prometheus:latest 6 | volumes: 7 | - prometheus_data:/prometheus 8 | - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml 9 | command: 10 | - '--config.file=/etc/prometheus/prometheus.yml' 11 | ports: 12 | - '9090:9090' 13 | grafana: 14 | image: grafana/grafana:latest 15 | volumes: 16 | - grafana_data:/var/lib/grafana 17 | - ./grafana/provisioning:/etc/grafana/provisioning 18 | - ./grafana/config.ini:/etc/grafana/config.ini 19 | - ./grafana/dashboards:/var/lib/grafana/dashboards 20 | environment: 21 | - GF_SECURITY_ADMIN_PASSWORD=illchangeitanyway 22 | depends_on: 23 | - prometheus 24 | ports: 25 | - '3000:3000' 26 | app: 27 | build: 28 | context: ./app 29 | dockerfile: Dockerfile 30 | ports: 31 | - '9200:9200' 32 | command: 'index.js' 33 | 34 | 35 | volumes: 36 | prometheus_data: {} 37 | grafana_data: {} 38 | -------------------------------------------------------------------------------- /grafana/config.ini: -------------------------------------------------------------------------------- 1 | [server] 2 | enable_gzip = true 3 | 4 | [users] 5 | default_theme = light 6 | 7 | [paths] 8 | provisioning = /etc/grafana/provisioning 9 | -------------------------------------------------------------------------------- /grafana/dashboards/simple.json: -------------------------------------------------------------------------------- 1 | { 2 | "annotations": { 3 | "list": [ 4 | { 5 | "builtIn": 1, 6 | "datasource": "-- Grafana --", 7 | "enable": true, 8 | "hide": true, 9 | "iconColor": "rgba(0, 211, 255, 1)", 10 | "name": "Annotations & Alerts", 11 | "type": "dashboard" 12 | } 13 | ] 14 | }, 15 | "editable": true, 16 | "gnetId": null, 17 | "graphTooltip": 0, 18 | "id": 1, 19 | "links": [], 20 | "panels": [ 21 | { 22 | "aliasColors": {}, 23 | "bars": false, 24 | "dashLength": 10, 25 | "dashes": false, 26 | "datasource": null, 27 | "fill": 1, 28 | "fillGradient": 0, 29 | "gridPos": { 30 | "h": 10, 31 | "w": 24, 32 | "x": 0, 33 | "y": 0 34 | }, 35 | "hiddenSeries": false, 36 | "id": 4, 37 | "legend": { 38 | "avg": false, 39 | "current": false, 40 | "max": false, 41 | "min": false, 42 | "rightSide": true, 43 | "show": true, 44 | "total": false, 45 | "values": false 46 | }, 47 | "lines": true, 48 | "linewidth": 1, 49 | "nullPointMode": "null", 50 | "options": { 51 | "dataLinks": [] 52 | }, 53 | "percentage": false, 54 | "pointradius": 2, 55 | "points": false, 56 | "renderer": "flot", 57 | "seriesOverrides": [], 58 | "spaceLength": 10, 59 | "stack": false, 60 | "steppedLine": false, 61 | "targets": [ 62 | { 63 | "expr": "sum(active_users)", 64 | "legendFormat": "Total users per all categories", 65 | "refId": "A" 66 | } 67 | ], 68 | "thresholds": [], 69 | "timeFrom": null, 70 | "timeRegions": [], 71 | "timeShift": null, 72 | "title": "Total users", 73 | "tooltip": { 74 | "shared": true, 75 | "sort": 0, 76 | "value_type": "individual" 77 | }, 78 | "transparent": true, 79 | "type": "graph", 80 | "xaxis": { 81 | "buckets": null, 82 | "mode": "time", 83 | "name": null, 84 | "show": true, 85 | "values": [] 86 | }, 87 | "yaxes": [ 88 | { 89 | "format": "short", 90 | "label": null, 91 | "logBase": 1, 92 | "max": null, 93 | "min": null, 94 | "show": true 95 | }, 96 | { 97 | "format": "short", 98 | "label": null, 99 | "logBase": 1, 100 | "max": null, 101 | "min": null, 102 | "show": true 103 | } 104 | ], 105 | "yaxis": { 106 | "align": false, 107 | "alignLevel": null 108 | } 109 | }, 110 | { 111 | "aliasColors": {}, 112 | "bars": false, 113 | "dashLength": 10, 114 | "dashes": false, 115 | "datasource": null, 116 | "fill": 1, 117 | "fillGradient": 0, 118 | "gridPos": { 119 | "h": 12, 120 | "w": 24, 121 | "x": 0, 122 | "y": 10 123 | }, 124 | "hiddenSeries": false, 125 | "id": 2, 126 | "legend": { 127 | "alignAsTable": true, 128 | "avg": true, 129 | "current": true, 130 | "max": true, 131 | "min": true, 132 | "rightSide": true, 133 | "show": true, 134 | "total": false, 135 | "values": true 136 | }, 137 | "lines": true, 138 | "linewidth": 1, 139 | "nullPointMode": "null", 140 | "options": { 141 | "dataLinks": [] 142 | }, 143 | "percentage": false, 144 | "pointradius": 2, 145 | "points": false, 146 | "renderer": "flot", 147 | "seriesOverrides": [], 148 | "spaceLength": 10, 149 | "stack": false, 150 | "steppedLine": false, 151 | "targets": [ 152 | { 153 | "expr": "active_users", 154 | "legendFormat": "{{ category }}", 155 | "refId": "A" 156 | } 157 | ], 158 | "thresholds": [], 159 | "timeFrom": null, 160 | "timeRegions": [], 161 | "timeShift": null, 162 | "title": "Active users", 163 | "tooltip": { 164 | "shared": true, 165 | "sort": 0, 166 | "value_type": "individual" 167 | }, 168 | "transparent": true, 169 | "type": "graph", 170 | "xaxis": { 171 | "buckets": null, 172 | "mode": "time", 173 | "name": null, 174 | "show": true, 175 | "values": [] 176 | }, 177 | "yaxes": [ 178 | { 179 | "format": "short", 180 | "label": null, 181 | "logBase": 1, 182 | "max": null, 183 | "min": null, 184 | "show": true 185 | }, 186 | { 187 | "format": "short", 188 | "label": null, 189 | "logBase": 1, 190 | "max": null, 191 | "min": null, 192 | "show": true 193 | } 194 | ], 195 | "yaxis": { 196 | "align": false, 197 | "alignLevel": null 198 | } 199 | } 200 | ], 201 | "schemaVersion": 21, 202 | "style": "dark", 203 | "tags": [], 204 | "templating": { 205 | "list": [] 206 | }, 207 | "time": { 208 | "from": "now-5m", 209 | "to": "now" 210 | }, 211 | "timepicker": { 212 | "refresh_intervals": [ 213 | "5s", 214 | "10s", 215 | "30s", 216 | "1m", 217 | "5m", 218 | "15m", 219 | "30m", 220 | "1h", 221 | "2h", 222 | "1d" 223 | ] 224 | }, 225 | "timezone": "", 226 | "title": "Example dashboard", 227 | "uid": "2xmZ0iwZk", 228 | "version": 2 229 | } 230 | -------------------------------------------------------------------------------- /grafana/provisioning/dashboards/all.yml: -------------------------------------------------------------------------------- 1 | - name: 'default' # name of this dashboard configuration (not dashboard itself) 2 | org_id: 1 # id of the org to hold the dashboard 3 | folder: '' # name of the folder to put the dashboard (http://docs.grafana.org/v5.0/reference/dashboard_folders/) 4 | type: 'file' # type of dashboard description (json files) 5 | options: 6 | folder: '/var/lib/grafana/dashboards' # where dashboards are 7 | -------------------------------------------------------------------------------- /grafana/provisioning/datasources/all.yml: -------------------------------------------------------------------------------- 1 | datasources: 2 | - name: 'prometheus-monitoring-1' 3 | type: 'prometheus' 4 | access: 'proxy' 5 | org_id: 1 6 | url: 'http://prometheus:9090' 7 | is_default: true 8 | version: 1 9 | editable: true 10 | -------------------------------------------------------------------------------- /prometheus/prometheus.yml: -------------------------------------------------------------------------------- 1 | scrape_configs: 2 | - job_name: 'prometheus' 3 | scrape_interval: 5s 4 | 5 | static_configs: 6 | - targets: [ 7 | 'app:9200', 8 | ] 9 | labels: 10 | service: 'app-exporter' 11 | group: 'testing' 12 | name: 'app-exporter' 13 | --------------------------------------------------------------------------------