├── .gitignore ├── dist ├── img │ ├── grallama-example.png │ ├── grallama-example-2.png │ ├── grallama-example-3.png │ ├── grallama-logo-large.png │ └── grallama-logo-small.png ├── src │ └── img │ │ ├── grallama-example.png │ │ ├── grallama-example-2.png │ │ ├── grallama-example-3.png │ │ ├── grallama-logo-large.png │ │ └── grallama-logo-small.png ├── module.js.map ├── axes_editor.html ├── module.js ├── plugin.json ├── module.html ├── rendering.js ├── css │ └── matrix.css ├── rendering.js.map ├── README.md ├── options_editor.html ├── grallama_ctrl.js.map └── grallama_ctrl.js ├── src ├── img │ ├── grallama-example.png │ ├── grallama-example-2.png │ ├── grallama-example-3.png │ ├── grallama-logo-large.png │ └── grallama-logo-small.png ├── module.js ├── axes_editor.html ├── plugin.json ├── rendering.js ├── module.html ├── css │ └── matrix.css ├── options_editor.html └── grallama_ctrl.js ├── LICENSE ├── package.json ├── Gruntfile.js ├── README.md └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea/* 3 | -------------------------------------------------------------------------------- /dist/img/grallama-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/img/grallama-example.png -------------------------------------------------------------------------------- /src/img/grallama-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/src/img/grallama-example.png -------------------------------------------------------------------------------- /dist/img/grallama-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/img/grallama-example-2.png -------------------------------------------------------------------------------- /dist/img/grallama-example-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/img/grallama-example-3.png -------------------------------------------------------------------------------- /src/img/grallama-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/src/img/grallama-example-2.png -------------------------------------------------------------------------------- /src/img/grallama-example-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/src/img/grallama-example-3.png -------------------------------------------------------------------------------- /src/img/grallama-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/src/img/grallama-logo-large.png -------------------------------------------------------------------------------- /src/img/grallama-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/src/img/grallama-logo-small.png -------------------------------------------------------------------------------- /dist/img/grallama-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/img/grallama-logo-large.png -------------------------------------------------------------------------------- /dist/img/grallama-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/img/grallama-logo-small.png -------------------------------------------------------------------------------- /dist/src/img/grallama-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/src/img/grallama-example.png -------------------------------------------------------------------------------- /dist/src/img/grallama-example-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/src/img/grallama-example-2.png -------------------------------------------------------------------------------- /dist/src/img/grallama-example-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/src/img/grallama-example-3.png -------------------------------------------------------------------------------- /dist/src/img/grallama-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/src/img/grallama-logo-large.png -------------------------------------------------------------------------------- /dist/src/img/grallama-logo-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dropbox/grallama-panel/master/dist/src/img/grallama-logo-small.png -------------------------------------------------------------------------------- /src/module.js: -------------------------------------------------------------------------------- 1 | import { GraLLAMACtrl } from './grallama_ctrl'; 2 | import { loadPluginCss } from 'app/plugins/sdk'; 3 | 4 | loadPluginCss({ 5 | dark: 'plugins/dropbox-grallama-panel/css/matrix.css', 6 | light: 'plugins/dropbox-grallama-panel/css/matrix.css', 7 | }); 8 | 9 | export { 10 | GraLLAMACtrl as PanelCtrl 11 | }; 12 | -------------------------------------------------------------------------------- /dist/module.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/module.js"],"names":["GraLLAMACtrl","loadPluginCss","dark","light"],"mappings":";;;;;;;;AAASA,kB,kBAAAA,Y;;AACAC,mB,kBAAAA,a;;;;AAETA,oBAAc;AACZC,cAAM,+CADM;AAEZC,eAAO;AAFK,OAAd;;2BAMEH,Y","file":"module.js","sourcesContent":["import { GraLLAMACtrl } from './grallama_ctrl';\nimport { loadPluginCss } from 'app/plugins/sdk';\n\nloadPluginCss({\n dark: 'plugins/dropbox-grallama-panel/css/matrix.css',\n light: 'plugins/dropbox-grallama-panel/css/matrix.css',\n});\n\nexport {\n GraLLAMACtrl as PanelCtrl\n};\n"]} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Dropbox, Inc. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /src/axes_editor.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Y-Axis
4 |
5 | Label 6 | 7 |
8 |
9 |
10 |
X-Axis
11 |
12 | Label 13 | 14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /dist/axes_editor.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Y-Axis
4 |
5 | Label 6 | 7 |
8 |
9 |
10 |
X-Axis
11 |
12 | Label 13 | 14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /dist/module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['./grallama_ctrl', 'app/plugins/sdk'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var GraLLAMACtrl, loadPluginCss; 7 | return { 8 | setters: [function (_grallama_ctrl) { 9 | GraLLAMACtrl = _grallama_ctrl.GraLLAMACtrl; 10 | }, function (_appPluginsSdk) { 11 | loadPluginCss = _appPluginsSdk.loadPluginCss; 12 | }], 13 | execute: function () { 14 | 15 | loadPluginCss({ 16 | dark: 'plugins/dropbox-grallama-panel/css/matrix.css', 17 | light: 'plugins/dropbox-grallama-panel/css/matrix.css' 18 | }); 19 | 20 | _export('PanelCtrl', GraLLAMACtrl); 21 | } 22 | }; 23 | }); 24 | //# sourceMappingURL=module.js.map 25 | -------------------------------------------------------------------------------- /src/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "panel", 3 | "name": "GraLLAMA", 4 | "id": "dropbox-grallama-panel", 5 | 6 | "info": { 7 | "description": "Matrix-like display for LLAMA data", 8 | "author": { 9 | "name": "Dropbox, Inc." 10 | }, 11 | "keywords": ["llama", "loss", "latency", "matrix", "panel"], 12 | "logos": { 13 | "small": "src/img/grallama-logo-small.png", 14 | "large": "src/img/grallama-logo-large.png" 15 | }, 16 | "links": [ 17 | {"name": "Project site", "url": "https://github.com/dropbox/grallama-panel"}, 18 | {"name": "Apache 2.0 License", "url": "https://github.com/dropbox/grallama-panel/blob/master/LICENSE"} 19 | ], 20 | "screenshots": [ 21 | {"name": "Example1", "path": "src/img/grallama-example.png"} 22 | ], 23 | "version": "0.1.2", 24 | "updated": "2019-07-02" 25 | }, 26 | 27 | "dependencies": { 28 | "grafanaVersion": "3.x.x", 29 | "plugins": [ ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /dist/plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "panel", 3 | "name": "GraLLAMA", 4 | "id": "dropbox-grallama-panel", 5 | 6 | "info": { 7 | "description": "Matrix-like display for LLAMA data", 8 | "author": { 9 | "name": "Dropbox, Inc." 10 | }, 11 | "keywords": ["llama", "loss", "latency", "matrix", "panel"], 12 | "logos": { 13 | "small": "src/img/grallama-logo-small.png", 14 | "large": "src/img/grallama-logo-large.png" 15 | }, 16 | "links": [ 17 | {"name": "Project site", "url": "https://github.com/dropbox/grallama-panel"}, 18 | {"name": "Apache 2.0 License", "url": "https://github.com/dropbox/grallama-panel/blob/master/LICENSE"} 19 | ], 20 | "screenshots": [ 21 | {"name": "Example1", "path": "src/img/grallama-example.png"} 22 | ], 23 | "version": "0.1.2", 24 | "updated": "2019-07-02" 25 | }, 26 | 27 | "dependencies": { 28 | "grafanaVersion": "3.x.x", 29 | "plugins": [ ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "GraLLAMA", 3 | "version": "0.1.2", 4 | "description": "Matrix-like display for LLAMA data", 5 | "main": "src/module.js", 6 | "keywords": [ 7 | "matrix", 8 | "llama", 9 | "latency", 10 | "loss", 11 | "panel", 12 | "plugin" 13 | ], 14 | "author": "Dropbox, Inc.", 15 | "license": "MIT", 16 | "devDependencies": { 17 | "babel": "~6.5.1", 18 | "grunt": "~0.4.5", 19 | "grunt-babel": "~6.0.0", 20 | "grunt-contrib-clean": "~0.6.0", 21 | "grunt-contrib-copy": "~0.8.2", 22 | "grunt-contrib-uglify": "~0.11.0", 23 | "grunt-contrib-watch": "^0.6.1", 24 | "grunt-execute": "~0.2.2", 25 | "grunt-systemjs-builder": "^0.2.5", 26 | "load-grunt-tasks": "~3.2.0" 27 | }, 28 | "dependencies": { 29 | "babel-plugin-transform-es2015-for-of": "^6.5.0", 30 | "babel-plugin-transform-es2015-modules-systemjs": "^6.5.0", 31 | "babel-preset-es2015": "^6.5.0", 32 | "lodash": "~4.0.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/rendering.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import $ from 'jquery'; 3 | 4 | export default function link(scope, elem, attrs, ctrl) { 5 | var data, panel, matrix; 6 | elem = elem.find('.matrix-panel'); 7 | var $tooltip = $('
'); 8 | 9 | ctrl.events.on('render', function() { 10 | render(); 11 | ctrl.renderingCompleted(); 12 | }); 13 | 14 | function setElementHeight() { 15 | try { 16 | var height = ctrl.height || panel.height || ctrl.row.height; 17 | if (_.isString(height)) { 18 | height = parseInt(height.replace('px', ''), 10); 19 | } 20 | 21 | height -= 5; // padding 22 | height -= panel.title ? 24 : 9; // subtract panel title bar 23 | 24 | elem.css('height', height + 'px'); 25 | 26 | return true; 27 | } catch(e) { // IE throws errors sometimes 28 | return false; 29 | } 30 | } 31 | 32 | function render() { 33 | if (!ctrl.data) { return; } 34 | 35 | data = ctrl.data; 36 | panel = ctrl.panel; 37 | matrix = ctrl.matrix; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /dist/module.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | {{ ctrl.matrix.summary_cell.value }} 6 | 7 | There 8 | is {{ ctrl.matrix.summary_cell.numUnhealthy }} unhealthy cell 9 | are {{ ctrl.matrix.summary_cell.numUnhealthy }} unhealthy cells 10 | 11 | 12 | All cells are healthy! 13 | 14 |
15 |
16 | {{ cell.value }} 17 | 18 | {{ ctrl.panel.yAxisLabel }}: {{ cell.yCat }}
19 | {{ ctrl.panel.xAxisLabel }}: {{ cell.xCat }}
20 | Value: {{ cell.value }} 21 |
22 |
23 |
24 |
25 |
26 |
27 | -------------------------------------------------------------------------------- /src/module.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | {{ ctrl.matrix.summary_cell.value }} 6 | 7 | There 8 | is {{ ctrl.matrix.summary_cell.numUnhealthy }} unhealthy cell 9 | are {{ ctrl.matrix.summary_cell.numUnhealthy }} unhealthy cells 10 | 11 | 12 | All cells are healthy! 13 | 14 |
15 |
16 | {{ cell.value }} 17 | 18 | {{ ctrl.panel.yAxisLabel }}: {{ cell.yCat }}
19 | {{ ctrl.panel.xAxisLabel }}: {{ cell.xCat }}
20 | Value: {{ cell.value }} 21 |
22 |
23 |
24 |
25 |
26 |
27 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | require('load-grunt-tasks')(grunt); 4 | 5 | grunt.loadNpmTasks('grunt-execute'); 6 | grunt.loadNpmTasks('grunt-contrib-clean'); 7 | 8 | grunt.initConfig({ 9 | 10 | clean: ["dist"], 11 | 12 | copy: { 13 | src_to_dist: { 14 | cwd: 'src', 15 | expand: true, 16 | src: ['**/*', '!**/*.js', '!**/*.scss'], 17 | dest: 'dist' 18 | }, 19 | img_to_dist: { 20 | cwd: 'src', 21 | expand: true, 22 | src: ['img/*'], 23 | dest: 'dist/src/' 24 | }, 25 | pluginDef: { 26 | expand: true, 27 | src: [ 'plugin.json', 'README.md' ], 28 | dest: 'dist', 29 | } 30 | }, 31 | 32 | watch: { 33 | rebuild_all: { 34 | files: ['src/**/*', 'plugin.json'], 35 | tasks: ['default'], 36 | options: {spawn: false} 37 | }, 38 | }, 39 | 40 | babel: { 41 | options: { 42 | sourceMap: true, 43 | presets: ["es2015"], 44 | plugins: ['transform-es2015-modules-systemjs', "transform-es2015-for-of"], 45 | }, 46 | dist: { 47 | files: [{ 48 | cwd: 'src', 49 | expand: true, 50 | src: ['*.js'], 51 | dest: 'dist', 52 | ext:'.js' 53 | }] 54 | }, 55 | }, 56 | 57 | }); 58 | 59 | grunt.registerTask('default', ['clean', 'copy:src_to_dist', 'copy:img_to_dist', 'copy:pluginDef', 'babel']); 60 | }; 61 | -------------------------------------------------------------------------------- /dist/rendering.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['lodash', 'jquery'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var _, $; 7 | 8 | function link(scope, elem, attrs, ctrl) { 9 | var data, panel, matrix; 10 | elem = elem.find('.matrix-panel'); 11 | var $tooltip = $('
'); 12 | 13 | ctrl.events.on('render', function () { 14 | render(); 15 | ctrl.renderingCompleted(); 16 | }); 17 | 18 | function setElementHeight() { 19 | try { 20 | var height = ctrl.height || panel.height || ctrl.row.height; 21 | if (_.isString(height)) { 22 | height = parseInt(height.replace('px', ''), 10); 23 | } 24 | 25 | height -= 5; // padding 26 | height -= panel.title ? 24 : 9; // subtract panel title bar 27 | 28 | elem.css('height', height + 'px'); 29 | 30 | return true; 31 | } catch (e) { 32 | // IE throws errors sometimes 33 | return false; 34 | } 35 | } 36 | 37 | function render() { 38 | if (!ctrl.data) { 39 | return; 40 | } 41 | 42 | data = ctrl.data; 43 | panel = ctrl.panel; 44 | matrix = ctrl.matrix; 45 | } 46 | } 47 | 48 | _export('default', link); 49 | 50 | return { 51 | setters: [function (_lodash) { 52 | _ = _lodash.default; 53 | }, function (_jquery) { 54 | $ = _jquery.default; 55 | }], 56 | execute: function () {} 57 | }; 58 | }); 59 | //# sourceMappingURL=rendering.js.map 60 | -------------------------------------------------------------------------------- /dist/css/matrix.css: -------------------------------------------------------------------------------- 1 | .graph-wrapper { 2 | /* This is all to allow scrolling if the matrix 3 | * gets too large in any dimension */ 4 | height: 100%; 5 | width: 100%; 6 | overflow: scroll; 7 | } 8 | 9 | .matrix-panel { 10 | display: grid; 11 | /* Could modify this to keep things tighter */ 12 | grid-gap: 2px; 13 | /* Using variable units for this results in uneven spacing */ 14 | /* grid-gap: 0.5em; */ 15 | /* This version keeps the columns small */ 16 | grid-auto-columns: min-content; 17 | /* This version will take up all the width, but prevents 18 | * big ones from taking up too much space */ 19 | /* grid-auto-columns: minmax(min-content, 1fr); */ 20 | /* This version is a tighter balance, keeping calls 21 | * from getting too wide, unless needed. So this version 22 | * won't actually take up the full width with smaller 23 | * sets of data */ 24 | grid-auto-columns: minmax(min-content, 10vmax); 25 | /* So headers are kept small if possible. 26 | * This only impacts the first column as 27 | * long as we're explicitly setting locations */ 28 | grid-template-columns: min-content; 29 | } 30 | 31 | .matrix-panel .grid-cell { 32 | /* Could modify this to keep things tighter */ 33 | padding: 0.5em; 34 | text-align: center; 35 | position: relative; /* Required for the tooltip */ 36 | } 37 | 38 | .grid-cell .matrix-tooltip { 39 | visibility: hidden; 40 | white-space: nowrap; 41 | background-color: black; 42 | text-align: left; 43 | padding: 1em; 44 | border-radius: 6px; 45 | /* Positioning of the tooltip */ 46 | position: absolute; 47 | z-index: 1; 48 | /* Maybe add for other positioning, but leave for now 49 | top: 100%; 50 | left: 50%; 51 | margin-left: -60px; */ 52 | } 53 | 54 | .grid-cell:hover .matrix-tooltip { 55 | visibility: visible; 56 | } 57 | 58 | .summary_cell { 59 | text-align:center; 60 | } 61 | -------------------------------------------------------------------------------- /src/css/matrix.css: -------------------------------------------------------------------------------- 1 | .graph-wrapper { 2 | /* This is all to allow scrolling if the matrix 3 | * gets too large in any dimension */ 4 | height: 100%; 5 | width: 100%; 6 | overflow: scroll; 7 | } 8 | 9 | .matrix-panel { 10 | display: grid; 11 | /* Could modify this to keep things tighter */ 12 | grid-gap: 2px; 13 | /* Using variable units for this results in uneven spacing */ 14 | /* grid-gap: 0.5em; */ 15 | /* This version keeps the columns small */ 16 | grid-auto-columns: min-content; 17 | /* This version will take up all the width, but prevents 18 | * big ones from taking up too much space */ 19 | /* grid-auto-columns: minmax(min-content, 1fr); */ 20 | /* This version is a tighter balance, keeping calls 21 | * from getting too wide, unless needed. So this version 22 | * won't actually take up the full width with smaller 23 | * sets of data */ 24 | grid-auto-columns: minmax(min-content, 10vmax); 25 | /* So headers are kept small if possible. 26 | * This only impacts the first column as 27 | * long as we're explicitly setting locations */ 28 | grid-template-columns: min-content; 29 | } 30 | 31 | .matrix-panel .grid-cell { 32 | /* Could modify this to keep things tighter */ 33 | padding: 0.5em; 34 | text-align: center; 35 | position: relative; /* Required for the tooltip */ 36 | } 37 | 38 | .grid-cell .matrix-tooltip { 39 | visibility: hidden; 40 | white-space: nowrap; 41 | background-color: black; 42 | text-align: left; 43 | padding: 1em; 44 | border-radius: 6px; 45 | /* Positioning of the tooltip */ 46 | position: absolute; 47 | z-index: 1; 48 | /* Maybe add for other positioning, but leave for now 49 | top: 100%; 50 | left: 50%; 51 | margin-left: -60px; */ 52 | } 53 | 54 | .grid-cell:hover .matrix-tooltip { 55 | visibility: visible; 56 | } 57 | 58 | .summary_cell { 59 | text-align:center; 60 | } 61 | -------------------------------------------------------------------------------- /dist/rendering.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/rendering.js"],"names":["link","scope","elem","attrs","ctrl","data","panel","matrix","find","$tooltip","$","events","on","render","renderingCompleted","setElementHeight","height","row","_","isString","parseInt","replace","title","css","e"],"mappings":";;;;;;;AAGe,WAASA,IAAT,CAAcC,KAAd,EAAqBC,IAArB,EAA2BC,KAA3B,EAAkCC,IAAlC,EAAwC;AACrD,QAAIC,IAAJ,EAAUC,KAAV,EAAiBC,MAAjB;AACAL,WAAOA,KAAKM,IAAL,CAAU,eAAV,CAAP;AACA,QAAIC,WAAWC,EAAE,oBAAF,CAAf;;AAEAN,SAAKO,MAAL,CAAYC,EAAZ,CAAe,QAAf,EAAyB,YAAW;AAClCC;AACAT,WAAKU,kBAAL;AACD,KAHD;;AAKA,aAASC,gBAAT,GAA4B;AAC1B,UAAI;AACF,YAAIC,SAASZ,KAAKY,MAAL,IAAeV,MAAMU,MAArB,IAA+BZ,KAAKa,GAAL,CAASD,MAArD;AACA,YAAIE,EAAEC,QAAF,CAAWH,MAAX,CAAJ,EAAwB;AACtBA,mBAASI,SAASJ,OAAOK,OAAP,CAAe,IAAf,EAAqB,EAArB,CAAT,EAAmC,EAAnC,CAAT;AACD;;AAEDL,kBAAU,CAAV,CANE,CAMW;AACbA,kBAAUV,MAAMgB,KAAN,GAAc,EAAd,GAAmB,CAA7B,CAPE,CAO8B;;AAEhCpB,aAAKqB,GAAL,CAAS,QAAT,EAAmBP,SAAS,IAA5B;;AAEA,eAAO,IAAP;AACD,OAZD,CAYE,OAAMQ,CAAN,EAAS;AAAE;AACX,eAAO,KAAP;AACD;AACF;;AAED,aAASX,MAAT,GAAkB;AAChB,UAAI,CAACT,KAAKC,IAAV,EAAgB;AAAE;AAAS;;AAE3BA,aAAOD,KAAKC,IAAZ;AACAC,cAAQF,KAAKE,KAAb;AACAC,eAASH,KAAKG,MAAd;AACD;AACF;;qBAnCuBP,I;;;;AAHjBkB,O;;AACAR,O","file":"rendering.js","sourcesContent":["import _ from 'lodash';\nimport $ from 'jquery';\n\nexport default function link(scope, elem, attrs, ctrl) {\n var data, panel, matrix;\n elem = elem.find('.matrix-panel');\n var $tooltip = $('
');\n\n ctrl.events.on('render', function() {\n render();\n ctrl.renderingCompleted();\n });\n\n function setElementHeight() {\n try {\n var height = ctrl.height || panel.height || ctrl.row.height;\n if (_.isString(height)) {\n height = parseInt(height.replace('px', ''), 10);\n }\n\n height -= 5; // padding\n height -= panel.title ? 24 : 9; // subtract panel title bar\n\n elem.css('height', height + 'px');\n\n return true;\n } catch(e) { // IE throws errors sometimes\n return false;\n }\n }\n\n function render() {\n if (!ctrl.data) { return; }\n\n data = ctrl.data;\n panel = ctrl.panel;\n matrix = ctrl.matrix;\n }\n}\n"]} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grafana GraLLAMA Panel 2 | 3 | 4 | 5 | GraLLAMA is a panel plugin for Grafana which visualizes the matrix-like data 6 | collected by the [LLAMA](https://github.com/dropbox/llama) project. See the 7 | LLAMA project on GitHub for more information: 8 | 9 | https://github.com/dropbox/llama 10 | 11 | ## Features 12 | * Displays loss percentages between sources and destinations. 13 | * Sources/Destinations are dynamically pulled from timeseries tags. 14 | * Changes cell color based on higher percentages. 15 | 16 | ![example1](src/img/grallama-example.png) 17 | ![example1](src/img/grallama-example-2.png) 18 | 19 | ## Compatibility 20 | This panel should work with the following datasources: 21 | [InfluxDB](https://grafana.net/plugins/influxdb) 22 | 23 | ## Installation 24 | Use the new grafana-cli tool to install grallama-panel from the commandline: 25 | 26 | ``` 27 | grafana-cli plugins install dropbox-grallama-panel 28 | ``` 29 | 30 | The plugin will be installed into your grafana plugins directory; the default 31 | is /var/lib/grafana/plugins if you installed the grafana package. 32 | 33 | More instructions on the cli tool can be found 34 | [here](http://docs.grafana.org/v3.0/plugins/installation/). 35 | 36 | You need the lastest grafana build for Grafana 3.0 to enable plugin support. 37 | You can get it here : http://grafana.org/download/builds.html 38 | 39 | ## Setup 40 | After installing the panel plugin follow these instructions to visualize 41 | the latest loss data from your running LLAMA deployment. 42 | 43 | 0. Setup a datasource for InfluxDB where LLAMA data is stored. 44 | 1. Add a new panel to a row in Grafana and select GraLLAMA. 45 | 2. Open the query editor and select InfluxDB and the measurement `loss`. 46 | 3. Select `mean()` as an aggregation (or others if you see fit). 47 | 4. Select `Group by` using exactly two tags; one of them will be the source 48 | tag and the other will be the destination tag. Also, use `fill(null)`. 49 | 5. Type into the `Alias by` field `-` (the hypen is 50 | important). If your source tag was `foo` and destination tag was `bar` then 51 | the field would look like this: `$tag_foo-$tag_bar` 52 | -------------------------------------------------------------------------------- /dist/README.md: -------------------------------------------------------------------------------- 1 | # Grafana GraLLAMA Panel 2 | 3 | 4 | 5 | GraLLAMA is a panel plugin for Grafana which visualizes the matrix-like data 6 | collected by the [LLAMA](https://github.com/dropbox/llama) project. See the 7 | LLAMA project on GitHub for more information: 8 | 9 | https://github.com/dropbox/llama 10 | 11 | ## Features 12 | * Displays loss percentages between sources and destinations. 13 | * Sources/Destinations are dynamically pulled from timeseries tags. 14 | * Changes cell color based on higher percentages. 15 | 16 | ![example1](src/img/grallama-example.png) 17 | ![example1](src/img/grallama-example-2.png) 18 | 19 | ## Compatibility 20 | This panel should work with the following datasources: 21 | [InfluxDB](https://grafana.net/plugins/influxdb) 22 | 23 | ## Installation 24 | Use the new grafana-cli tool to install grallama-panel from the commandline: 25 | 26 | ``` 27 | grafana-cli plugins install dropbox-grallama-panel 28 | ``` 29 | 30 | The plugin will be installed into your grafana plugins directory; the default 31 | is /var/lib/grafana/plugins if you installed the grafana package. 32 | 33 | More instructions on the cli tool can be found 34 | [here](http://docs.grafana.org/v3.0/plugins/installation/). 35 | 36 | You need the lastest grafana build for Grafana 3.0 to enable plugin support. 37 | You can get it here : http://grafana.org/download/builds.html 38 | 39 | ## Setup 40 | After installing the panel plugin follow these instructions to visualize 41 | the latest loss data from your running LLAMA deployment. 42 | 43 | 0. Setup a datasource for InfluxDB where LLAMA data is stored. 44 | 1. Add a new panel to a row in Grafana and select GraLLAMA. 45 | 2. Open the query editor and select InfluxDB and the measurement `loss`. 46 | 3. Select `mean()` as an aggregation (or others if you see fit). 47 | 4. Select `Group by` using exactly two tags; one of them will be the source 48 | tag and the other will be the destination tag. Also, use `fill(null)`. 49 | 5. Type into the `Alias by` field `-` (the hypen is 50 | important). If your source tag was `foo` and destination tag was `bar` then 51 | the field would look like this: `$tag_foo-$tag_bar` 52 | -------------------------------------------------------------------------------- /dist/options_editor.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Coloring
4 |
5 | 6 | 7 |
8 |
9 |
10 | 13 | 14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | Invert 24 | 25 | 26 |
27 |
28 |
29 |
Tooltip
30 |
31 | 32 |
33 |
34 |
35 |
Separator
36 |
37 | String 38 | 39 |
40 |
41 |
42 |
Aggregation
43 |
44 | Stat 45 | 46 |
47 |
48 |
49 |
Health Check
50 |
51 | Condition 52 | 53 | 54 |
55 |
56 |
57 | -------------------------------------------------------------------------------- /src/options_editor.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
Coloring
4 |
5 | 6 | 7 |
8 |
9 |
10 | 13 | 14 |
15 |
16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | Invert 24 | 25 | 26 |
27 |
28 |
29 |
Tooltip
30 |
31 | 32 |
33 |
34 |
35 |
Separator
36 |
37 | String 38 | 39 |
40 |
41 |
42 |
Aggregation
43 |
44 | Stat 45 | 46 |
47 |
48 |
49 |
Health Check
50 |
51 | Condition 52 | 53 | 54 |
55 |
56 |
57 | -------------------------------------------------------------------------------- /src/grallama_ctrl.js: -------------------------------------------------------------------------------- 1 | import {MetricsPanelCtrl} from 'app/plugins/sdk'; 2 | import _ from 'lodash'; 3 | import kbn from 'app/core/utils/kbn'; 4 | import TimeSeries from 'app/core/time_series'; 5 | import rendering from './rendering'; 6 | 7 | export class GraLLAMACtrl extends MetricsPanelCtrl { 8 | 9 | constructor($scope, $injector, $rootScope) { 10 | super($scope, $injector); 11 | this.$rootScope = $rootScope; 12 | 13 | var panelDefaults = { 14 | legend: { 15 | show: true, // disable/enable legend 16 | values: true 17 | }, 18 | links: [], 19 | datasource: null, 20 | maxDataPoints: 3, 21 | interval: null, 22 | targets: [{}], 23 | cacheTimeout: null, 24 | nullPointMode: 'connected', 25 | legendType: 'Under graph', 26 | aliasColors: {}, 27 | format: 'short', 28 | valueName: 'avg', 29 | valueNameOptions: [ 30 | { text: "Min", value: "min" }, 31 | { text: "Max", value: "max" }, 32 | { text: "Average", value: "avg" }, 33 | { text: "Current", value: "current" }, 34 | { text: "Total", value: "total" } 35 | ], 36 | strokeWidth: 1, 37 | fontSize: '60%', 38 | combine: { 39 | threshold: 0.0, 40 | label: 'Others' 41 | }, 42 | tooltipHover: false, // Should there be a tooltip for cells 43 | colorBackground: true, // Should the cell background be colored 44 | colorValue: false, // Should the cell value be colored 45 | colors: ['#6ea009', "#D38E02", "#C86501", "#BD3D01", "#AD0000"], 46 | thresholds: '0,0.2,1,5,99', 47 | xAxisLabel: 'X-Axis', 48 | yAxisLabel: 'Y-Axis', 49 | separator: '-', 50 | healthCheckThreshold: '0.2', 51 | healthCheckOperator: '<', 52 | healthCheckOperatorOptions: [{ text: "<", value: "<" }, { text: ">=", value: ">=" }, { text: "=", value: "=" } ] 53 | }; 54 | 55 | _.defaults(this.panel, panelDefaults); 56 | _.defaults(this.panel.legend, panelDefaults.legend); 57 | 58 | this.events.on('render', this.onRender.bind(this)); 59 | this.events.on('data-received', this.onDataReceived.bind(this)); 60 | this.events.on('data-error', this.onDataError.bind(this)); 61 | this.events.on('data-snapshot-load', this.onDataReceived.bind(this)); 62 | this.events.on('init-edit-mode', this.onInitEditMode.bind(this)); 63 | } 64 | 65 | onInitEditMode() { 66 | this.addEditorTab('Axes', 'public/plugins/dropbox-grallama-panel/axes_editor.html', 2); 67 | this.addEditorTab('Options', 'public/plugins/dropbox-grallama-panel/options_editor.html', 3); 68 | this.unitFormats = kbn.getUnitFormats(); 69 | } 70 | 71 | setUnitFormat(subItem) { 72 | this.panel.format = subItem.value; 73 | this.render(); 74 | } 75 | 76 | onDataError() { 77 | this.series = []; 78 | this.render(); 79 | } 80 | 81 | changeSeriesColor(series, color) { 82 | series.color = color; 83 | this.panel.aliasColors[series.alias] = series.color; 84 | this.render(); 85 | } 86 | 87 | onRender() { 88 | this.data = this.parseSeries(this.series); 89 | this.matrix = this.parseMatrix(this.series); 90 | } 91 | 92 | performHealthCheck(dataValue, op, threshold) { 93 | if (op == '=') { 94 | return dataValue == threshold 95 | } else if(op == '<') { 96 | return dataValue < threshold 97 | } else { 98 | return dataValue >= threshold 99 | } 100 | } 101 | 102 | parseMatrix(series) { 103 | var that = this; 104 | var matrix = {}; 105 | matrix['data'] = {}; // Raw data 106 | matrix['cells'] = []; // Cells to render 107 | matrix['summary_cell'] = { style: {}, 108 | value: '', 109 | numUnhealthy: 0, 110 | } // Summary about matrix (i.e how many numbers are too small/big) 111 | 112 | // Unique values for each row and column 113 | var yCats = new Set(); 114 | var xCats = new Set(); 115 | // These are needed for referencing in loops below 116 | let colorBackground = this.panel.colorBackground; 117 | let colorValue = this.panel.colorValue; 118 | let thresholds = this.panel.thresholds.split(',').map(function(strVale) { 119 | return Number(strVale.trim()); 120 | }); 121 | let colors = this.panel.colors; 122 | let separator = this.panel.separator; 123 | let valueName = this.panel.valueName; 124 | 125 | var numUnhealthyCells = 0; 126 | let op = this.panel.healthCheckOperator; 127 | let threshold = parseFloat(this.panel.healthCheckThreshold); 128 | 129 | // Parse all the series into their buckets 130 | angular.forEach(series, function(datapoint) { 131 | var agg = datapoint.stats[valueName]; 132 | var datavalue = Number(agg).toFixed(1); 133 | if (!that.performHealthCheck(datavalue, op, threshold)) { 134 | numUnhealthyCells += 1; 135 | } 136 | let [yCat, xCat] = datapoint.label.split(separator); 137 | yCats.add(yCat); 138 | xCats.add(xCat); 139 | if (!(yCat in matrix.data)) { 140 | // Create the object if it doesn't exist 141 | matrix.data[yCat] = {}; 142 | } 143 | matrix.data[yCat][xCat] = datavalue; 144 | }); 145 | 146 | if (numUnhealthyCells > 0) { 147 | matrix['summary_cell']['style']['color'] = 'red'; 148 | matrix['summary_cell']['value'] = 'x'; 149 | } 150 | else { 151 | matrix['summary_cell']['style']['color'] = 'green'; 152 | matrix['summary_cell']['value'] = '✓'; 153 | } 154 | matrix['summary_cell']['numUnhealthy'] = numUnhealthyCells; 155 | 156 | // Sort the axis categories 157 | yCats = Array.from(yCats).sort(); 158 | xCats = Array.from(xCats).sort(); 159 | 160 | // Create the x axis label cells for the matrix 161 | let rowNum = 1; 162 | let colNum = 1; 163 | for (let xCat of xCats) { 164 | colNum++; // Start 1 cell in, like the data 165 | matrix['cells'].push({ 166 | value: xCat, 167 | style: { 168 | "grid-row": rowNum.toString(), 169 | "grid-column": colNum.toString(), 170 | } 171 | }); 172 | } 173 | 174 | // Create the rest of the rows 175 | for (let yCat of yCats) { 176 | rowNum++; // Start 1 cell in, like the data 177 | colNum = 1; // This needs to be reset for each row 178 | // Add a cell for the row header 179 | matrix['cells'].push({ 180 | value: yCat, 181 | style: { 182 | "grid-row": rowNum.toString(), 183 | "grid-column": colNum.toString(), 184 | "white-space": "nowrap", // Should move this into external CSS 185 | "text-align": "right", // Should move this into external CSS 186 | } 187 | }); 188 | // Create the data cells 189 | for (let xCat of xCats) { 190 | colNum++; 191 | let value = matrix.data[yCat][xCat]; 192 | let cell = { 193 | 'yCat': yCat, 194 | 'xCat': xCat, 195 | 'value': value, 196 | 'tooltip': this.panel.tooltipHover, 197 | 'style': { 198 | // These must be strings, otherwise they get silently ignored 199 | 'grid-row': rowNum.toString(), 200 | 'grid-column': colNum.toString(), 201 | }, 202 | }; 203 | // Add coloring to the cell (if needed) and only if it has a value 204 | if ((colorBackground || colorValue) && cell.value) { 205 | let color = colors[0]; // Start with the base, and update if greater than thresholds 206 | angular.forEach(thresholds, function(limit, i) { 207 | if (cell.value >= limit) { color = colors[i+1]; } 208 | }); 209 | if (colorBackground) { cell.style['background-color'] = color; } 210 | if (colorValue) { cell.style['color'] = color; } 211 | } 212 | // Add the cell to the matrix 213 | matrix.cells.push(cell) 214 | } 215 | } 216 | return matrix; 217 | } 218 | 219 | parseSeries(series) { 220 | return _.map(this.series, (serie, i) => { 221 | return { 222 | label: serie.alias, 223 | data: serie.stats[this.panel.valueName], 224 | color: this.panel.aliasColors[serie.alias] || this.$rootScope.colors[i] 225 | }; 226 | }); 227 | } 228 | 229 | onDataReceived(dataList) { 230 | this.series = dataList.map(this.seriesHandler.bind(this)); 231 | this.data = this.parseSeries(this.series); 232 | this.matrix = this.parseMatrix(this.series); 233 | this.render(this.data); 234 | } 235 | 236 | seriesHandler(seriesData) { 237 | var series = new TimeSeries({ 238 | datapoints: seriesData.datapoints, 239 | alias: seriesData.target 240 | }); 241 | 242 | series.flotpairs = series.getFlotPairs(this.panel.nullPointMode); 243 | return series; 244 | } 245 | 246 | link(scope, elem, attrs, ctrl) { 247 | rendering(scope, elem, attrs, ctrl); 248 | } 249 | 250 | // Stolen from SingleStat 251 | // Try to subclass at some point to get this for free 252 | // I don't think we're actually using this specific option at the moment. 253 | setColoring(options) { 254 | if (options.background) { 255 | this.panel.colorValue = false; 256 | this.panel.colors = ['rgba(71, 212, 59, 0.4)', 'rgba(245, 150, 40, 0.73)', 'rgba(225, 40, 40, 0.59)']; 257 | } else { 258 | this.panel.colorBackground = false; 259 | this.panel.colors = ['rgba(50, 172, 45, 0.97)', 'rgba(237, 129, 40, 0.89)', 'rgba(245, 54, 54, 0.9)']; 260 | } 261 | this.render(); 262 | } 263 | 264 | invertColorOrder() { 265 | // This seems to be designed for only 3 266 | // var tmp = this.panel.colors[0]; 267 | // this.panel.colors[0] = this.panel.colors[2]; 268 | // this.panel.colors[2] = tmp; 269 | // This is so much cleaner, easier, and scalable 270 | this.panel.colors.reverse(); 271 | this.render(); 272 | } 273 | 274 | onColorChange(panelColorIndex) { 275 | return color => { 276 | this.panel.colors[panelColorIndex] = color; 277 | this.render(); 278 | }; 279 | } 280 | 281 | } 282 | 283 | GraLLAMACtrl.templateUrl = 'module.html'; 284 | -------------------------------------------------------------------------------- /dist/grallama_ctrl.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../src/grallama_ctrl.js"],"names":["MetricsPanelCtrl","_","kbn","TimeSeries","rendering","GraLLAMACtrl","$scope","$injector","$rootScope","panelDefaults","legend","show","values","links","datasource","maxDataPoints","interval","targets","cacheTimeout","nullPointMode","legendType","aliasColors","format","valueName","valueNameOptions","text","value","strokeWidth","fontSize","combine","threshold","label","tooltipHover","colorBackground","colorValue","colors","thresholds","xAxisLabel","yAxisLabel","separator","healthCheckThreshold","healthCheckOperator","healthCheckOperatorOptions","defaults","panel","events","on","onRender","bind","onDataReceived","onDataError","onInitEditMode","addEditorTab","unitFormats","getUnitFormats","subItem","render","series","color","alias","data","parseSeries","matrix","parseMatrix","dataValue","op","that","style","numUnhealthy","yCats","Set","xCats","split","map","strVale","Number","trim","numUnhealthyCells","parseFloat","angular","forEach","datapoint","agg","stats","datavalue","toFixed","performHealthCheck","yCat","xCat","add","Array","from","sort","rowNum","colNum","push","toString","cell","limit","i","cells","serie","dataList","seriesHandler","seriesData","datapoints","target","flotpairs","getFlotPairs","scope","elem","attrs","ctrl","options","background","reverse","panelColorIndex","templateUrl"],"mappings":"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","file":"grallama_ctrl.js","sourcesContent":["import {MetricsPanelCtrl} from 'app/plugins/sdk';\nimport _ from 'lodash';\nimport kbn from 'app/core/utils/kbn';\nimport TimeSeries from 'app/core/time_series';\nimport rendering from './rendering';\n\nexport class GraLLAMACtrl extends MetricsPanelCtrl {\n\n constructor($scope, $injector, $rootScope) {\n super($scope, $injector);\n this.$rootScope = $rootScope;\n\n var panelDefaults = {\n legend: {\n show: true, // disable/enable legend\n values: true\n },\n links: [],\n datasource: null,\n maxDataPoints: 3,\n interval: null,\n targets: [{}],\n cacheTimeout: null,\n nullPointMode: 'connected',\n legendType: 'Under graph',\n aliasColors: {},\n format: 'short',\n valueName: 'avg',\n valueNameOptions: [\n { text: \"Min\", value: \"min\" },\n { text: \"Max\", value: \"max\" },\n { text: \"Average\", value: \"avg\" },\n { text: \"Current\", value: \"current\" },\n { text: \"Total\", value: \"total\" }\n ],\n strokeWidth: 1,\n fontSize: '60%',\n combine: {\n threshold: 0.0,\n label: 'Others'\n },\n tooltipHover: false, // Should there be a tooltip for cells\n colorBackground: true, // Should the cell background be colored\n colorValue: false, // Should the cell value be colored\n colors: ['#6ea009', \"#D38E02\", \"#C86501\", \"#BD3D01\", \"#AD0000\"],\n thresholds: '0,0.2,1,5,99',\n xAxisLabel: 'X-Axis',\n yAxisLabel: 'Y-Axis',\n separator: '-',\n healthCheckThreshold: '0.2',\n healthCheckOperator: '<',\n healthCheckOperatorOptions: [{ text: \"<\", value: \"<\" }, { text: \">=\", value: \">=\" }, { text: \"=\", value: \"=\" } ]\n };\n\n _.defaults(this.panel, panelDefaults);\n _.defaults(this.panel.legend, panelDefaults.legend);\n\n this.events.on('render', this.onRender.bind(this));\n this.events.on('data-received', this.onDataReceived.bind(this));\n this.events.on('data-error', this.onDataError.bind(this));\n this.events.on('data-snapshot-load', this.onDataReceived.bind(this));\n this.events.on('init-edit-mode', this.onInitEditMode.bind(this));\n }\n\n onInitEditMode() {\n this.addEditorTab('Axes', 'public/plugins/dropbox-grallama-panel/axes_editor.html', 2);\n this.addEditorTab('Options', 'public/plugins/dropbox-grallama-panel/options_editor.html', 3);\n this.unitFormats = kbn.getUnitFormats();\n }\n\n setUnitFormat(subItem) {\n this.panel.format = subItem.value;\n this.render();\n }\n\n onDataError() {\n this.series = [];\n this.render();\n }\n\n changeSeriesColor(series, color) {\n series.color = color;\n this.panel.aliasColors[series.alias] = series.color;\n this.render();\n }\n\n onRender() {\n this.data = this.parseSeries(this.series);\n this.matrix = this.parseMatrix(this.series);\n }\n\n performHealthCheck(dataValue, op, threshold) {\n if (op == '=') {\n return dataValue == threshold\n } else if(op == '<') {\n return dataValue < threshold\n } else {\n return dataValue >= threshold\n }\n }\n\n parseMatrix(series) {\n var that = this;\n var matrix = {};\n matrix['data'] = {}; // Raw data\n matrix['cells'] = []; // Cells to render\n matrix['summary_cell'] = { style: {},\n value: '',\n numUnhealthy: 0,\n } // Summary about matrix (i.e how many numbers are too small/big)\n\n // Unique values for each row and column\n var yCats = new Set();\n var xCats = new Set();\n // These are needed for referencing in loops below\n let colorBackground = this.panel.colorBackground;\n let colorValue = this.panel.colorValue;\n let thresholds = this.panel.thresholds.split(',').map(function(strVale) {\n return Number(strVale.trim());\n });\n let colors = this.panel.colors;\n let separator = this.panel.separator;\n let valueName = this.panel.valueName;\n\n var numUnhealthyCells = 0;\n let op = this.panel.healthCheckOperator;\n let threshold = parseFloat(this.panel.healthCheckThreshold);\n\n // Parse all the series into their buckets\n angular.forEach(series, function(datapoint) {\n var agg = datapoint.stats[valueName];\n var datavalue = Number(agg).toFixed(1);\n if (!that.performHealthCheck(datavalue, op, threshold)) {\n numUnhealthyCells += 1;\n }\n let [yCat, xCat] = datapoint.label.split(separator);\n yCats.add(yCat);\n xCats.add(xCat);\n if (!(yCat in matrix.data)) {\n // Create the object if it doesn't exist\n matrix.data[yCat] = {};\n }\n matrix.data[yCat][xCat] = datavalue;\n });\n\n if (numUnhealthyCells > 0) {\n matrix['summary_cell']['style']['color'] = 'red';\n matrix['summary_cell']['value'] = 'x';\n }\n else {\n matrix['summary_cell']['style']['color'] = 'green';\n matrix['summary_cell']['value'] = '✓';\n }\n matrix['summary_cell']['numUnhealthy'] = numUnhealthyCells;\n \n // Sort the axis categories\n yCats = Array.from(yCats).sort();\n xCats = Array.from(xCats).sort();\n\n // Create the x axis label cells for the matrix\n let rowNum = 1;\n let colNum = 1;\n for (let xCat of xCats) {\n colNum++; // Start 1 cell in, like the data\n matrix['cells'].push({\n value: xCat,\n style: {\n \"grid-row\": rowNum.toString(),\n \"grid-column\": colNum.toString(),\n }\n });\n }\n\n // Create the rest of the rows\n for (let yCat of yCats) {\n rowNum++; // Start 1 cell in, like the data\n colNum = 1; // This needs to be reset for each row\n // Add a cell for the row header\n matrix['cells'].push({\n value: yCat,\n style: {\n \"grid-row\": rowNum.toString(),\n \"grid-column\": colNum.toString(),\n \"white-space\": \"nowrap\", // Should move this into external CSS\n \"text-align\": \"right\", // Should move this into external CSS\n }\n });\n // Create the data cells\n for (let xCat of xCats) {\n colNum++;\n let value = matrix.data[yCat][xCat];\n let cell = {\n 'yCat': yCat,\n 'xCat': xCat,\n 'value': value,\n 'tooltip': this.panel.tooltipHover,\n 'style': {\n // These must be strings, otherwise they get silently ignored\n 'grid-row': rowNum.toString(),\n 'grid-column': colNum.toString(),\n },\n };\n // Add coloring to the cell (if needed) and only if it has a value\n if ((colorBackground || colorValue) && cell.value) {\n let color = colors[0]; // Start with the base, and update if greater than thresholds\n angular.forEach(thresholds, function(limit, i) {\n if (cell.value >= limit) { color = colors[i+1]; }\n });\n if (colorBackground) { cell.style['background-color'] = color; }\n if (colorValue) { cell.style['color'] = color; }\n }\n // Add the cell to the matrix\n matrix.cells.push(cell)\n }\n }\n return matrix;\n }\n\n parseSeries(series) {\n return _.map(this.series, (serie, i) => {\n return {\n label: serie.alias,\n data: serie.stats[this.panel.valueName],\n color: this.panel.aliasColors[serie.alias] || this.$rootScope.colors[i]\n };\n });\n }\n\n onDataReceived(dataList) {\n this.series = dataList.map(this.seriesHandler.bind(this));\n this.data = this.parseSeries(this.series);\n this.matrix = this.parseMatrix(this.series);\n this.render(this.data);\n }\n\n seriesHandler(seriesData) {\n var series = new TimeSeries({\n datapoints: seriesData.datapoints,\n alias: seriesData.target\n });\n\n series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);\n return series;\n }\n\n link(scope, elem, attrs, ctrl) {\n rendering(scope, elem, attrs, ctrl);\n }\n\n// Stolen from SingleStat\n// Try to subclass at some point to get this for free\n// I don't think we're actually using this specific option at the moment.\n setColoring(options) {\n if (options.background) {\n this.panel.colorValue = false;\n this.panel.colors = ['rgba(71, 212, 59, 0.4)', 'rgba(245, 150, 40, 0.73)', 'rgba(225, 40, 40, 0.59)'];\n } else {\n this.panel.colorBackground = false;\n this.panel.colors = ['rgba(50, 172, 45, 0.97)', 'rgba(237, 129, 40, 0.89)', 'rgba(245, 54, 54, 0.9)'];\n }\n this.render();\n }\n\n invertColorOrder() {\n // This seems to be designed for only 3\n // var tmp = this.panel.colors[0];\n // this.panel.colors[0] = this.panel.colors[2];\n // this.panel.colors[2] = tmp;\n // This is so much cleaner, easier, and scalable\n this.panel.colors.reverse();\n this.render();\n }\n\n onColorChange(panelColorIndex) {\n return color => {\n this.panel.colors[panelColorIndex] = color;\n this.render();\n };\n }\n\n}\n\nGraLLAMACtrl.templateUrl = 'module.html';\n"]} -------------------------------------------------------------------------------- /dist/grallama_ctrl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | System.register(['app/plugins/sdk', 'lodash', 'app/core/utils/kbn', 'app/core/time_series', './rendering'], function (_export, _context) { 4 | "use strict"; 5 | 6 | var MetricsPanelCtrl, _, kbn, TimeSeries, rendering, _slicedToArray, _createClass, GraLLAMACtrl; 7 | 8 | function _classCallCheck(instance, Constructor) { 9 | if (!(instance instanceof Constructor)) { 10 | throw new TypeError("Cannot call a class as a function"); 11 | } 12 | } 13 | 14 | function _possibleConstructorReturn(self, call) { 15 | if (!self) { 16 | throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 17 | } 18 | 19 | return call && (typeof call === "object" || typeof call === "function") ? call : self; 20 | } 21 | 22 | function _inherits(subClass, superClass) { 23 | if (typeof superClass !== "function" && superClass !== null) { 24 | throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); 25 | } 26 | 27 | subClass.prototype = Object.create(superClass && superClass.prototype, { 28 | constructor: { 29 | value: subClass, 30 | enumerable: false, 31 | writable: true, 32 | configurable: true 33 | } 34 | }); 35 | if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; 36 | } 37 | 38 | return { 39 | setters: [function (_appPluginsSdk) { 40 | MetricsPanelCtrl = _appPluginsSdk.MetricsPanelCtrl; 41 | }, function (_lodash) { 42 | _ = _lodash.default; 43 | }, function (_appCoreUtilsKbn) { 44 | kbn = _appCoreUtilsKbn.default; 45 | }, function (_appCoreTime_series) { 46 | TimeSeries = _appCoreTime_series.default; 47 | }, function (_rendering) { 48 | rendering = _rendering.default; 49 | }], 50 | execute: function () { 51 | _slicedToArray = function () { 52 | function sliceIterator(arr, i) { 53 | var _arr = []; 54 | var _n = true; 55 | var _d = false; 56 | var _e = undefined; 57 | 58 | try { 59 | for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { 60 | _arr.push(_s.value); 61 | 62 | if (i && _arr.length === i) break; 63 | } 64 | } catch (err) { 65 | _d = true; 66 | _e = err; 67 | } finally { 68 | try { 69 | if (!_n && _i["return"]) _i["return"](); 70 | } finally { 71 | if (_d) throw _e; 72 | } 73 | } 74 | 75 | return _arr; 76 | } 77 | 78 | return function (arr, i) { 79 | if (Array.isArray(arr)) { 80 | return arr; 81 | } else if (Symbol.iterator in Object(arr)) { 82 | return sliceIterator(arr, i); 83 | } else { 84 | throw new TypeError("Invalid attempt to destructure non-iterable instance"); 85 | } 86 | }; 87 | }(); 88 | 89 | _createClass = function () { 90 | function defineProperties(target, props) { 91 | for (var i = 0; i < props.length; i++) { 92 | var descriptor = props[i]; 93 | descriptor.enumerable = descriptor.enumerable || false; 94 | descriptor.configurable = true; 95 | if ("value" in descriptor) descriptor.writable = true; 96 | Object.defineProperty(target, descriptor.key, descriptor); 97 | } 98 | } 99 | 100 | return function (Constructor, protoProps, staticProps) { 101 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 102 | if (staticProps) defineProperties(Constructor, staticProps); 103 | return Constructor; 104 | }; 105 | }(); 106 | 107 | _export('GraLLAMACtrl', GraLLAMACtrl = function (_MetricsPanelCtrl) { 108 | _inherits(GraLLAMACtrl, _MetricsPanelCtrl); 109 | 110 | function GraLLAMACtrl($scope, $injector, $rootScope) { 111 | _classCallCheck(this, GraLLAMACtrl); 112 | 113 | var _this = _possibleConstructorReturn(this, (GraLLAMACtrl.__proto__ || Object.getPrototypeOf(GraLLAMACtrl)).call(this, $scope, $injector)); 114 | 115 | _this.$rootScope = $rootScope; 116 | 117 | var panelDefaults = { 118 | legend: { 119 | show: true, // disable/enable legend 120 | values: true 121 | }, 122 | links: [], 123 | datasource: null, 124 | maxDataPoints: 3, 125 | interval: null, 126 | targets: [{}], 127 | cacheTimeout: null, 128 | nullPointMode: 'connected', 129 | legendType: 'Under graph', 130 | aliasColors: {}, 131 | format: 'short', 132 | valueName: 'avg', 133 | valueNameOptions: [{ text: "Min", value: "min" }, { text: "Max", value: "max" }, { text: "Average", value: "avg" }, { text: "Current", value: "current" }, { text: "Total", value: "total" }], 134 | strokeWidth: 1, 135 | fontSize: '60%', 136 | combine: { 137 | threshold: 0.0, 138 | label: 'Others' 139 | }, 140 | tooltipHover: false, // Should there be a tooltip for cells 141 | colorBackground: true, // Should the cell background be colored 142 | colorValue: false, // Should the cell value be colored 143 | colors: ['#6ea009', "#D38E02", "#C86501", "#BD3D01", "#AD0000"], 144 | thresholds: '0,0.2,1,5,99', 145 | xAxisLabel: 'X-Axis', 146 | yAxisLabel: 'Y-Axis', 147 | separator: '-', 148 | healthCheckThreshold: '0.2', 149 | healthCheckOperator: '<', 150 | healthCheckOperatorOptions: [{ text: "<", value: "<" }, { text: ">=", value: ">=" }, { text: "=", value: "=" }] 151 | }; 152 | 153 | _.defaults(_this.panel, panelDefaults); 154 | _.defaults(_this.panel.legend, panelDefaults.legend); 155 | 156 | _this.events.on('render', _this.onRender.bind(_this)); 157 | _this.events.on('data-received', _this.onDataReceived.bind(_this)); 158 | _this.events.on('data-error', _this.onDataError.bind(_this)); 159 | _this.events.on('data-snapshot-load', _this.onDataReceived.bind(_this)); 160 | _this.events.on('init-edit-mode', _this.onInitEditMode.bind(_this)); 161 | return _this; 162 | } 163 | 164 | _createClass(GraLLAMACtrl, [{ 165 | key: 'onInitEditMode', 166 | value: function onInitEditMode() { 167 | this.addEditorTab('Axes', 'public/plugins/dropbox-grallama-panel/axes_editor.html', 2); 168 | this.addEditorTab('Options', 'public/plugins/dropbox-grallama-panel/options_editor.html', 3); 169 | this.unitFormats = kbn.getUnitFormats(); 170 | } 171 | }, { 172 | key: 'setUnitFormat', 173 | value: function setUnitFormat(subItem) { 174 | this.panel.format = subItem.value; 175 | this.render(); 176 | } 177 | }, { 178 | key: 'onDataError', 179 | value: function onDataError() { 180 | this.series = []; 181 | this.render(); 182 | } 183 | }, { 184 | key: 'changeSeriesColor', 185 | value: function changeSeriesColor(series, color) { 186 | series.color = color; 187 | this.panel.aliasColors[series.alias] = series.color; 188 | this.render(); 189 | } 190 | }, { 191 | key: 'onRender', 192 | value: function onRender() { 193 | this.data = this.parseSeries(this.series); 194 | this.matrix = this.parseMatrix(this.series); 195 | } 196 | }, { 197 | key: 'performHealthCheck', 198 | value: function performHealthCheck(dataValue, op, threshold) { 199 | if (op == '=') { 200 | return dataValue == threshold; 201 | } else if (op == '<') { 202 | return dataValue < threshold; 203 | } else { 204 | return dataValue >= threshold; 205 | } 206 | } 207 | }, { 208 | key: 'parseMatrix', 209 | value: function parseMatrix(series) { 210 | var _this2 = this; 211 | 212 | var that = this; 213 | var matrix = {}; 214 | matrix['data'] = {}; // Raw data 215 | matrix['cells'] = []; // Cells to render 216 | matrix['summary_cell'] = { style: {}, 217 | value: '', 218 | numUnhealthy: 0 // Summary about matrix (i.e how many numbers are too small/big) 219 | 220 | // Unique values for each row and column 221 | };var yCats = new Set(); 222 | var xCats = new Set(); 223 | // These are needed for referencing in loops below 224 | var colorBackground = this.panel.colorBackground; 225 | var colorValue = this.panel.colorValue; 226 | var thresholds = this.panel.thresholds.split(',').map(function (strVale) { 227 | return Number(strVale.trim()); 228 | }); 229 | var colors = this.panel.colors; 230 | var separator = this.panel.separator; 231 | var valueName = this.panel.valueName; 232 | 233 | var numUnhealthyCells = 0; 234 | var op = this.panel.healthCheckOperator; 235 | var threshold = parseFloat(this.panel.healthCheckThreshold); 236 | 237 | // Parse all the series into their buckets 238 | angular.forEach(series, function (datapoint) { 239 | var agg = datapoint.stats[valueName]; 240 | var datavalue = Number(agg).toFixed(1); 241 | if (!that.performHealthCheck(datavalue, op, threshold)) { 242 | numUnhealthyCells += 1; 243 | } 244 | 245 | var _datapoint$label$spli = datapoint.label.split(separator), 246 | _datapoint$label$spli2 = _slicedToArray(_datapoint$label$spli, 2), 247 | yCat = _datapoint$label$spli2[0], 248 | xCat = _datapoint$label$spli2[1]; 249 | 250 | yCats.add(yCat); 251 | xCats.add(xCat); 252 | if (!(yCat in matrix.data)) { 253 | // Create the object if it doesn't exist 254 | matrix.data[yCat] = {}; 255 | } 256 | matrix.data[yCat][xCat] = datavalue; 257 | }); 258 | 259 | if (numUnhealthyCells > 0) { 260 | matrix['summary_cell']['style']['color'] = 'red'; 261 | matrix['summary_cell']['value'] = 'x'; 262 | } else { 263 | matrix['summary_cell']['style']['color'] = 'green'; 264 | matrix['summary_cell']['value'] = '✓'; 265 | } 266 | matrix['summary_cell']['numUnhealthy'] = numUnhealthyCells; 267 | 268 | // Sort the axis categories 269 | yCats = Array.from(yCats).sort(); 270 | xCats = Array.from(xCats).sort(); 271 | 272 | // Create the x axis label cells for the matrix 273 | var rowNum = 1; 274 | var colNum = 1; 275 | var _iteratorNormalCompletion = true; 276 | var _didIteratorError = false; 277 | var _iteratorError = undefined; 278 | 279 | try { 280 | for (var _iterator = xCats[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { 281 | var xCat = _step.value; 282 | 283 | colNum++; // Start 1 cell in, like the data 284 | matrix['cells'].push({ 285 | value: xCat, 286 | style: { 287 | "grid-row": rowNum.toString(), 288 | "grid-column": colNum.toString() 289 | } 290 | }); 291 | } 292 | 293 | // Create the rest of the rows 294 | } catch (err) { 295 | _didIteratorError = true; 296 | _iteratorError = err; 297 | } finally { 298 | try { 299 | if (!_iteratorNormalCompletion && _iterator.return) { 300 | _iterator.return(); 301 | } 302 | } finally { 303 | if (_didIteratorError) { 304 | throw _iteratorError; 305 | } 306 | } 307 | } 308 | 309 | var _iteratorNormalCompletion2 = true; 310 | var _didIteratorError2 = false; 311 | var _iteratorError2 = undefined; 312 | 313 | try { 314 | for (var _iterator2 = yCats[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { 315 | var yCat = _step2.value; 316 | 317 | rowNum++; // Start 1 cell in, like the data 318 | colNum = 1; // This needs to be reset for each row 319 | // Add a cell for the row header 320 | matrix['cells'].push({ 321 | value: yCat, 322 | style: { 323 | "grid-row": rowNum.toString(), 324 | "grid-column": colNum.toString(), 325 | "white-space": "nowrap", // Should move this into external CSS 326 | "text-align": "right" // Should move this into external CSS 327 | } 328 | }); 329 | // Create the data cells 330 | var _iteratorNormalCompletion3 = true; 331 | var _didIteratorError3 = false; 332 | var _iteratorError3 = undefined; 333 | 334 | try { 335 | var _loop = function _loop() { 336 | var xCat = _step3.value; 337 | 338 | colNum++; 339 | var value = matrix.data[yCat][xCat]; 340 | var cell = { 341 | 'yCat': yCat, 342 | 'xCat': xCat, 343 | 'value': value, 344 | 'tooltip': _this2.panel.tooltipHover, 345 | 'style': { 346 | // These must be strings, otherwise they get silently ignored 347 | 'grid-row': rowNum.toString(), 348 | 'grid-column': colNum.toString() 349 | } 350 | }; 351 | // Add coloring to the cell (if needed) and only if it has a value 352 | if ((colorBackground || colorValue) && cell.value) { 353 | var color = colors[0]; // Start with the base, and update if greater than thresholds 354 | angular.forEach(thresholds, function (limit, i) { 355 | if (cell.value >= limit) { 356 | color = colors[i + 1]; 357 | } 358 | }); 359 | if (colorBackground) { 360 | cell.style['background-color'] = color; 361 | } 362 | if (colorValue) { 363 | cell.style['color'] = color; 364 | } 365 | } 366 | // Add the cell to the matrix 367 | matrix.cells.push(cell); 368 | }; 369 | 370 | for (var _iterator3 = xCats[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { 371 | _loop(); 372 | } 373 | } catch (err) { 374 | _didIteratorError3 = true; 375 | _iteratorError3 = err; 376 | } finally { 377 | try { 378 | if (!_iteratorNormalCompletion3 && _iterator3.return) { 379 | _iterator3.return(); 380 | } 381 | } finally { 382 | if (_didIteratorError3) { 383 | throw _iteratorError3; 384 | } 385 | } 386 | } 387 | } 388 | } catch (err) { 389 | _didIteratorError2 = true; 390 | _iteratorError2 = err; 391 | } finally { 392 | try { 393 | if (!_iteratorNormalCompletion2 && _iterator2.return) { 394 | _iterator2.return(); 395 | } 396 | } finally { 397 | if (_didIteratorError2) { 398 | throw _iteratorError2; 399 | } 400 | } 401 | } 402 | 403 | return matrix; 404 | } 405 | }, { 406 | key: 'parseSeries', 407 | value: function parseSeries(series) { 408 | var _this3 = this; 409 | 410 | return _.map(this.series, function (serie, i) { 411 | return { 412 | label: serie.alias, 413 | data: serie.stats[_this3.panel.valueName], 414 | color: _this3.panel.aliasColors[serie.alias] || _this3.$rootScope.colors[i] 415 | }; 416 | }); 417 | } 418 | }, { 419 | key: 'onDataReceived', 420 | value: function onDataReceived(dataList) { 421 | this.series = dataList.map(this.seriesHandler.bind(this)); 422 | this.data = this.parseSeries(this.series); 423 | this.matrix = this.parseMatrix(this.series); 424 | this.render(this.data); 425 | } 426 | }, { 427 | key: 'seriesHandler', 428 | value: function seriesHandler(seriesData) { 429 | var series = new TimeSeries({ 430 | datapoints: seriesData.datapoints, 431 | alias: seriesData.target 432 | }); 433 | 434 | series.flotpairs = series.getFlotPairs(this.panel.nullPointMode); 435 | return series; 436 | } 437 | }, { 438 | key: 'link', 439 | value: function link(scope, elem, attrs, ctrl) { 440 | rendering(scope, elem, attrs, ctrl); 441 | } 442 | }, { 443 | key: 'setColoring', 444 | value: function setColoring(options) { 445 | if (options.background) { 446 | this.panel.colorValue = false; 447 | this.panel.colors = ['rgba(71, 212, 59, 0.4)', 'rgba(245, 150, 40, 0.73)', 'rgba(225, 40, 40, 0.59)']; 448 | } else { 449 | this.panel.colorBackground = false; 450 | this.panel.colors = ['rgba(50, 172, 45, 0.97)', 'rgba(237, 129, 40, 0.89)', 'rgba(245, 54, 54, 0.9)']; 451 | } 452 | this.render(); 453 | } 454 | }, { 455 | key: 'invertColorOrder', 456 | value: function invertColorOrder() { 457 | // This seems to be designed for only 3 458 | // var tmp = this.panel.colors[0]; 459 | // this.panel.colors[0] = this.panel.colors[2]; 460 | // this.panel.colors[2] = tmp; 461 | // This is so much cleaner, easier, and scalable 462 | this.panel.colors.reverse(); 463 | this.render(); 464 | } 465 | }, { 466 | key: 'onColorChange', 467 | value: function onColorChange(panelColorIndex) { 468 | var _this4 = this; 469 | 470 | return function (color) { 471 | _this4.panel.colors[panelColorIndex] = color; 472 | _this4.render(); 473 | }; 474 | } 475 | }]); 476 | 477 | return GraLLAMACtrl; 478 | }(MetricsPanelCtrl)); 479 | 480 | _export('GraLLAMACtrl', GraLLAMACtrl); 481 | 482 | GraLLAMACtrl.templateUrl = 'module.html'; 483 | } 484 | }; 485 | }); 486 | //# sourceMappingURL=grallama_ctrl.js.map 487 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | abbrev@1: 6 | version "1.1.1" 7 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 8 | 9 | align-text@^0.1.1, align-text@^0.1.3: 10 | version "0.1.4" 11 | resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" 12 | dependencies: 13 | kind-of "^3.0.2" 14 | longest "^1.0.1" 15 | repeat-string "^1.5.2" 16 | 17 | amdefine@>=0.0.4: 18 | version "1.0.1" 19 | resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" 20 | 21 | ansi-regex@^2.0.0: 22 | version "2.1.1" 23 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 24 | 25 | ansi-styles@^2.2.1: 26 | version "2.2.1" 27 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 28 | 29 | "argparse@~ 0.1.11": 30 | version "0.1.16" 31 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-0.1.16.tgz#cfd01e0fbba3d6caed049fbd758d40f65196f57c" 32 | dependencies: 33 | underscore "~1.7.0" 34 | underscore.string "~2.4.0" 35 | 36 | array-differ@^1.0.0: 37 | version "1.0.0" 38 | resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" 39 | 40 | array-union@^1.0.1: 41 | version "1.0.2" 42 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 43 | dependencies: 44 | array-uniq "^1.0.1" 45 | 46 | array-uniq@^1.0.1: 47 | version "1.0.3" 48 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 49 | 50 | arrify@^1.0.0: 51 | version "1.0.1" 52 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 53 | 54 | async@~0.1.22: 55 | version "0.1.22" 56 | resolved "https://registry.yarnpkg.com/async/-/async-0.1.22.tgz#0fc1aaa088a0e3ef0ebe2d8831bab0dcf8845061" 57 | 58 | async@~0.2.6, async@~0.2.9: 59 | version "0.2.10" 60 | resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" 61 | 62 | babel-code-frame@^6.26.0: 63 | version "6.26.0" 64 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 65 | dependencies: 66 | chalk "^1.1.3" 67 | esutils "^2.0.2" 68 | js-tokens "^3.0.2" 69 | 70 | babel-core@^6.0.12, babel-core@^6.26.0, babel-core@^6.9.0: 71 | version "6.26.0" 72 | resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" 73 | dependencies: 74 | babel-code-frame "^6.26.0" 75 | babel-generator "^6.26.0" 76 | babel-helpers "^6.24.1" 77 | babel-messages "^6.23.0" 78 | babel-register "^6.26.0" 79 | babel-runtime "^6.26.0" 80 | babel-template "^6.26.0" 81 | babel-traverse "^6.26.0" 82 | babel-types "^6.26.0" 83 | babylon "^6.18.0" 84 | convert-source-map "^1.5.0" 85 | debug "^2.6.8" 86 | json5 "^0.5.1" 87 | lodash "^4.17.4" 88 | minimatch "^3.0.4" 89 | path-is-absolute "^1.0.1" 90 | private "^0.1.7" 91 | slash "^1.0.0" 92 | source-map "^0.5.6" 93 | 94 | babel-generator@^6.26.0: 95 | version "6.26.1" 96 | resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" 97 | dependencies: 98 | babel-messages "^6.23.0" 99 | babel-runtime "^6.26.0" 100 | babel-types "^6.26.0" 101 | detect-indent "^4.0.0" 102 | jsesc "^1.3.0" 103 | lodash "^4.17.4" 104 | source-map "^0.5.7" 105 | trim-right "^1.0.1" 106 | 107 | babel-helper-call-delegate@^6.24.1: 108 | version "6.24.1" 109 | resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" 110 | dependencies: 111 | babel-helper-hoist-variables "^6.24.1" 112 | babel-runtime "^6.22.0" 113 | babel-traverse "^6.24.1" 114 | babel-types "^6.24.1" 115 | 116 | babel-helper-define-map@^6.24.1: 117 | version "6.26.0" 118 | resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" 119 | dependencies: 120 | babel-helper-function-name "^6.24.1" 121 | babel-runtime "^6.26.0" 122 | babel-types "^6.26.0" 123 | lodash "^4.17.4" 124 | 125 | babel-helper-function-name@^6.24.1: 126 | version "6.24.1" 127 | resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" 128 | dependencies: 129 | babel-helper-get-function-arity "^6.24.1" 130 | babel-runtime "^6.22.0" 131 | babel-template "^6.24.1" 132 | babel-traverse "^6.24.1" 133 | babel-types "^6.24.1" 134 | 135 | babel-helper-get-function-arity@^6.24.1: 136 | version "6.24.1" 137 | resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" 138 | dependencies: 139 | babel-runtime "^6.22.0" 140 | babel-types "^6.24.1" 141 | 142 | babel-helper-hoist-variables@^6.24.1: 143 | version "6.24.1" 144 | resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" 145 | dependencies: 146 | babel-runtime "^6.22.0" 147 | babel-types "^6.24.1" 148 | 149 | babel-helper-optimise-call-expression@^6.24.1: 150 | version "6.24.1" 151 | resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" 152 | dependencies: 153 | babel-runtime "^6.22.0" 154 | babel-types "^6.24.1" 155 | 156 | babel-helper-regex@^6.24.1: 157 | version "6.26.0" 158 | resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" 159 | dependencies: 160 | babel-runtime "^6.26.0" 161 | babel-types "^6.26.0" 162 | lodash "^4.17.4" 163 | 164 | babel-helper-replace-supers@^6.24.1: 165 | version "6.24.1" 166 | resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" 167 | dependencies: 168 | babel-helper-optimise-call-expression "^6.24.1" 169 | babel-messages "^6.23.0" 170 | babel-runtime "^6.22.0" 171 | babel-template "^6.24.1" 172 | babel-traverse "^6.24.1" 173 | babel-types "^6.24.1" 174 | 175 | babel-helpers@^6.24.1: 176 | version "6.24.1" 177 | resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" 178 | dependencies: 179 | babel-runtime "^6.22.0" 180 | babel-template "^6.24.1" 181 | 182 | babel-messages@^6.23.0: 183 | version "6.23.0" 184 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" 185 | dependencies: 186 | babel-runtime "^6.22.0" 187 | 188 | babel-plugin-check-es2015-constants@^6.22.0: 189 | version "6.22.0" 190 | resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" 191 | dependencies: 192 | babel-runtime "^6.22.0" 193 | 194 | babel-plugin-transform-cjs-system-wrapper@^0.3.0: 195 | version "0.3.0" 196 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-cjs-system-wrapper/-/babel-plugin-transform-cjs-system-wrapper-0.3.0.tgz#f5759f29becd356faab7af52c99cde8e7bad0b21" 197 | dependencies: 198 | babel-template "^6.9.0" 199 | 200 | babel-plugin-transform-es2015-arrow-functions@^6.22.0: 201 | version "6.22.0" 202 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" 203 | dependencies: 204 | babel-runtime "^6.22.0" 205 | 206 | babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: 207 | version "6.22.0" 208 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" 209 | dependencies: 210 | babel-runtime "^6.22.0" 211 | 212 | babel-plugin-transform-es2015-block-scoping@^6.24.1: 213 | version "6.26.0" 214 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" 215 | dependencies: 216 | babel-runtime "^6.26.0" 217 | babel-template "^6.26.0" 218 | babel-traverse "^6.26.0" 219 | babel-types "^6.26.0" 220 | lodash "^4.17.4" 221 | 222 | babel-plugin-transform-es2015-classes@^6.24.1: 223 | version "6.24.1" 224 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" 225 | dependencies: 226 | babel-helper-define-map "^6.24.1" 227 | babel-helper-function-name "^6.24.1" 228 | babel-helper-optimise-call-expression "^6.24.1" 229 | babel-helper-replace-supers "^6.24.1" 230 | babel-messages "^6.23.0" 231 | babel-runtime "^6.22.0" 232 | babel-template "^6.24.1" 233 | babel-traverse "^6.24.1" 234 | babel-types "^6.24.1" 235 | 236 | babel-plugin-transform-es2015-computed-properties@^6.24.1: 237 | version "6.24.1" 238 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" 239 | dependencies: 240 | babel-runtime "^6.22.0" 241 | babel-template "^6.24.1" 242 | 243 | babel-plugin-transform-es2015-destructuring@^6.22.0: 244 | version "6.23.0" 245 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" 246 | dependencies: 247 | babel-runtime "^6.22.0" 248 | 249 | babel-plugin-transform-es2015-duplicate-keys@^6.24.1: 250 | version "6.24.1" 251 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" 252 | dependencies: 253 | babel-runtime "^6.22.0" 254 | babel-types "^6.24.1" 255 | 256 | babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.5.0: 257 | version "6.23.0" 258 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" 259 | dependencies: 260 | babel-runtime "^6.22.0" 261 | 262 | babel-plugin-transform-es2015-function-name@^6.24.1: 263 | version "6.24.1" 264 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" 265 | dependencies: 266 | babel-helper-function-name "^6.24.1" 267 | babel-runtime "^6.22.0" 268 | babel-types "^6.24.1" 269 | 270 | babel-plugin-transform-es2015-literals@^6.22.0: 271 | version "6.22.0" 272 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" 273 | dependencies: 274 | babel-runtime "^6.22.0" 275 | 276 | babel-plugin-transform-es2015-modules-amd@^6.24.1: 277 | version "6.24.1" 278 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" 279 | dependencies: 280 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 281 | babel-runtime "^6.22.0" 282 | babel-template "^6.24.1" 283 | 284 | babel-plugin-transform-es2015-modules-commonjs@^6.24.1: 285 | version "6.26.0" 286 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" 287 | dependencies: 288 | babel-plugin-transform-strict-mode "^6.24.1" 289 | babel-runtime "^6.26.0" 290 | babel-template "^6.26.0" 291 | babel-types "^6.26.0" 292 | 293 | babel-plugin-transform-es2015-modules-systemjs@^6.24.1, babel-plugin-transform-es2015-modules-systemjs@^6.5.0, babel-plugin-transform-es2015-modules-systemjs@^6.6.5: 294 | version "6.24.1" 295 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" 296 | dependencies: 297 | babel-helper-hoist-variables "^6.24.1" 298 | babel-runtime "^6.22.0" 299 | babel-template "^6.24.1" 300 | 301 | babel-plugin-transform-es2015-modules-umd@^6.24.1: 302 | version "6.24.1" 303 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" 304 | dependencies: 305 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 306 | babel-runtime "^6.22.0" 307 | babel-template "^6.24.1" 308 | 309 | babel-plugin-transform-es2015-object-super@^6.24.1: 310 | version "6.24.1" 311 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" 312 | dependencies: 313 | babel-helper-replace-supers "^6.24.1" 314 | babel-runtime "^6.22.0" 315 | 316 | babel-plugin-transform-es2015-parameters@^6.24.1: 317 | version "6.24.1" 318 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" 319 | dependencies: 320 | babel-helper-call-delegate "^6.24.1" 321 | babel-helper-get-function-arity "^6.24.1" 322 | babel-runtime "^6.22.0" 323 | babel-template "^6.24.1" 324 | babel-traverse "^6.24.1" 325 | babel-types "^6.24.1" 326 | 327 | babel-plugin-transform-es2015-shorthand-properties@^6.24.1: 328 | version "6.24.1" 329 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" 330 | dependencies: 331 | babel-runtime "^6.22.0" 332 | babel-types "^6.24.1" 333 | 334 | babel-plugin-transform-es2015-spread@^6.22.0: 335 | version "6.22.0" 336 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" 337 | dependencies: 338 | babel-runtime "^6.22.0" 339 | 340 | babel-plugin-transform-es2015-sticky-regex@^6.24.1: 341 | version "6.24.1" 342 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" 343 | dependencies: 344 | babel-helper-regex "^6.24.1" 345 | babel-runtime "^6.22.0" 346 | babel-types "^6.24.1" 347 | 348 | babel-plugin-transform-es2015-template-literals@^6.22.0: 349 | version "6.22.0" 350 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" 351 | dependencies: 352 | babel-runtime "^6.22.0" 353 | 354 | babel-plugin-transform-es2015-typeof-symbol@^6.22.0: 355 | version "6.23.0" 356 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" 357 | dependencies: 358 | babel-runtime "^6.22.0" 359 | 360 | babel-plugin-transform-es2015-unicode-regex@^6.24.1: 361 | version "6.24.1" 362 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" 363 | dependencies: 364 | babel-helper-regex "^6.24.1" 365 | babel-runtime "^6.22.0" 366 | regexpu-core "^2.0.0" 367 | 368 | babel-plugin-transform-global-system-wrapper@0.0.1: 369 | version "0.0.1" 370 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-global-system-wrapper/-/babel-plugin-transform-global-system-wrapper-0.0.1.tgz#afb469cec0e04689b9fe7e8b1fd280fc94a6d8f2" 371 | dependencies: 372 | babel-template "^6.9.0" 373 | 374 | babel-plugin-transform-regenerator@^6.24.1: 375 | version "6.26.0" 376 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" 377 | dependencies: 378 | regenerator-transform "^0.10.0" 379 | 380 | babel-plugin-transform-strict-mode@^6.24.1: 381 | version "6.24.1" 382 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" 383 | dependencies: 384 | babel-runtime "^6.22.0" 385 | babel-types "^6.24.1" 386 | 387 | babel-plugin-transform-system-register@0.0.1: 388 | version "0.0.1" 389 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-system-register/-/babel-plugin-transform-system-register-0.0.1.tgz#9dff40390c2763ac518f0b2ad7c5ea4f65a5be25" 390 | 391 | babel-preset-es2015@^6.5.0: 392 | version "6.24.1" 393 | resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" 394 | dependencies: 395 | babel-plugin-check-es2015-constants "^6.22.0" 396 | babel-plugin-transform-es2015-arrow-functions "^6.22.0" 397 | babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" 398 | babel-plugin-transform-es2015-block-scoping "^6.24.1" 399 | babel-plugin-transform-es2015-classes "^6.24.1" 400 | babel-plugin-transform-es2015-computed-properties "^6.24.1" 401 | babel-plugin-transform-es2015-destructuring "^6.22.0" 402 | babel-plugin-transform-es2015-duplicate-keys "^6.24.1" 403 | babel-plugin-transform-es2015-for-of "^6.22.0" 404 | babel-plugin-transform-es2015-function-name "^6.24.1" 405 | babel-plugin-transform-es2015-literals "^6.22.0" 406 | babel-plugin-transform-es2015-modules-amd "^6.24.1" 407 | babel-plugin-transform-es2015-modules-commonjs "^6.24.1" 408 | babel-plugin-transform-es2015-modules-systemjs "^6.24.1" 409 | babel-plugin-transform-es2015-modules-umd "^6.24.1" 410 | babel-plugin-transform-es2015-object-super "^6.24.1" 411 | babel-plugin-transform-es2015-parameters "^6.24.1" 412 | babel-plugin-transform-es2015-shorthand-properties "^6.24.1" 413 | babel-plugin-transform-es2015-spread "^6.22.0" 414 | babel-plugin-transform-es2015-sticky-regex "^6.24.1" 415 | babel-plugin-transform-es2015-template-literals "^6.22.0" 416 | babel-plugin-transform-es2015-typeof-symbol "^6.22.0" 417 | babel-plugin-transform-es2015-unicode-regex "^6.24.1" 418 | babel-plugin-transform-regenerator "^6.24.1" 419 | 420 | babel-register@^6.26.0: 421 | version "6.26.0" 422 | resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" 423 | dependencies: 424 | babel-core "^6.26.0" 425 | babel-runtime "^6.26.0" 426 | core-js "^2.5.0" 427 | home-or-tmp "^2.0.0" 428 | lodash "^4.17.4" 429 | mkdirp "^0.5.1" 430 | source-map-support "^0.4.15" 431 | 432 | babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: 433 | version "6.26.0" 434 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 435 | dependencies: 436 | core-js "^2.4.0" 437 | regenerator-runtime "^0.11.0" 438 | 439 | babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.9.0: 440 | version "6.26.0" 441 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" 442 | dependencies: 443 | babel-runtime "^6.26.0" 444 | babel-traverse "^6.26.0" 445 | babel-types "^6.26.0" 446 | babylon "^6.18.0" 447 | lodash "^4.17.4" 448 | 449 | babel-traverse@^6.24.1, babel-traverse@^6.26.0: 450 | version "6.26.0" 451 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" 452 | dependencies: 453 | babel-code-frame "^6.26.0" 454 | babel-messages "^6.23.0" 455 | babel-runtime "^6.26.0" 456 | babel-types "^6.26.0" 457 | babylon "^6.18.0" 458 | debug "^2.6.8" 459 | globals "^9.18.0" 460 | invariant "^2.2.2" 461 | lodash "^4.17.4" 462 | 463 | babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: 464 | version "6.26.0" 465 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" 466 | dependencies: 467 | babel-runtime "^6.26.0" 468 | esutils "^2.0.2" 469 | lodash "^4.17.4" 470 | to-fast-properties "^1.0.3" 471 | 472 | babel@~6.5.1: 473 | version "6.5.2" 474 | resolved "http://registry.npmjs.org/babel/-/babel-6.5.2.tgz#59140607438270920047ff56f02b2d8630c2d129" 475 | 476 | babylon@^6.18.0: 477 | version "6.18.0" 478 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" 479 | 480 | balanced-match@^1.0.0: 481 | version "1.0.0" 482 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 483 | 484 | bluebird@^3.3.4: 485 | version "3.5.1" 486 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" 487 | 488 | brace-expansion@^1.0.0, brace-expansion@^1.1.7: 489 | version "1.1.11" 490 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 491 | dependencies: 492 | balanced-match "^1.0.0" 493 | concat-map "0.0.1" 494 | 495 | camelcase@^1.0.2: 496 | version "1.2.1" 497 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" 498 | 499 | center-align@^0.1.1: 500 | version "0.1.3" 501 | resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" 502 | dependencies: 503 | align-text "^0.1.3" 504 | lazy-cache "^1.0.3" 505 | 506 | chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: 507 | version "1.1.3" 508 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 509 | dependencies: 510 | ansi-styles "^2.2.1" 511 | escape-string-regexp "^1.0.2" 512 | has-ansi "^2.0.0" 513 | strip-ansi "^3.0.0" 514 | supports-color "^2.0.0" 515 | 516 | cliui@^2.1.0: 517 | version "2.1.0" 518 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" 519 | dependencies: 520 | center-align "^0.1.1" 521 | right-align "^0.1.1" 522 | wordwrap "0.0.2" 523 | 524 | coffee-script@~1.3.3: 525 | version "1.3.3" 526 | resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.3.3.tgz#150d6b4cb522894369efed6a2101c20bc7f4a4f4" 527 | 528 | colors@~0.6.2: 529 | version "0.6.2" 530 | resolved "https://registry.yarnpkg.com/colors/-/colors-0.6.2.tgz#2423fe6678ac0c5dae8852e5d0e5be08c997abcc" 531 | 532 | commander@2.9.x: 533 | version "2.9.0" 534 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" 535 | dependencies: 536 | graceful-readlink ">= 1.0.0" 537 | 538 | concat-map@0.0.1: 539 | version "0.0.1" 540 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 541 | 542 | convert-source-map@^1.5.0: 543 | version "1.5.1" 544 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" 545 | 546 | core-js@^2.4.0, core-js@^2.5.0: 547 | version "2.5.4" 548 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.4.tgz#f2c8bf181f2a80b92f360121429ce63a2f0aeae0" 549 | 550 | d@1: 551 | version "1.0.0" 552 | resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" 553 | dependencies: 554 | es5-ext "^0.10.9" 555 | 556 | data-uri-to-buffer@0.0.4: 557 | version "0.0.4" 558 | resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-0.0.4.tgz#46e13ab9da8e309745c8d01ce547213ebdb2fe3f" 559 | 560 | dateformat@1.0.2-1.2.3: 561 | version "1.0.2-1.2.3" 562 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.2-1.2.3.tgz#b0220c02de98617433b72851cf47de3df2cdbee9" 563 | 564 | debug@^2.6.8: 565 | version "2.6.9" 566 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 567 | dependencies: 568 | ms "2.0.0" 569 | 570 | debug@~0.7.0: 571 | version "0.7.4" 572 | resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" 573 | 574 | decamelize@^1.0.0: 575 | version "1.2.0" 576 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 577 | 578 | detect-indent@^4.0.0: 579 | version "4.0.0" 580 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" 581 | dependencies: 582 | repeating "^2.0.0" 583 | 584 | duplexer@^0.1.1: 585 | version "0.1.1" 586 | resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" 587 | 588 | es5-ext@^0.10.12, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: 589 | version "0.10.42" 590 | resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.42.tgz#8c07dd33af04d5dcd1310b5cef13bea63a89ba8d" 591 | dependencies: 592 | es6-iterator "~2.0.3" 593 | es6-symbol "~3.1.1" 594 | next-tick "1" 595 | 596 | es6-iterator@~2.0.3: 597 | version "2.0.3" 598 | resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" 599 | dependencies: 600 | d "1" 601 | es5-ext "^0.10.35" 602 | es6-symbol "^3.1.1" 603 | 604 | es6-symbol@^3.1.1, es6-symbol@~3.1.1: 605 | version "3.1.1" 606 | resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" 607 | dependencies: 608 | d "1" 609 | es5-ext "~0.10.14" 610 | 611 | es6-template-strings@^2.0.0: 612 | version "2.0.1" 613 | resolved "https://registry.yarnpkg.com/es6-template-strings/-/es6-template-strings-2.0.1.tgz#b166c6a62562f478bb7775f6ca96103a599b4b2c" 614 | dependencies: 615 | es5-ext "^0.10.12" 616 | esniff "^1.1" 617 | 618 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 619 | version "1.0.5" 620 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 621 | 622 | esniff@^1.1: 623 | version "1.1.0" 624 | resolved "https://registry.yarnpkg.com/esniff/-/esniff-1.1.0.tgz#c66849229f91464dede2e0d40201ed6abf65f2ac" 625 | dependencies: 626 | d "1" 627 | es5-ext "^0.10.12" 628 | 629 | "esprima@~ 1.0.2": 630 | version "1.0.4" 631 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" 632 | 633 | esutils@^2.0.2: 634 | version "2.0.2" 635 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 636 | 637 | eventemitter2@~0.4.13: 638 | version "0.4.14" 639 | resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" 640 | 641 | exit@~0.1.1: 642 | version "0.1.2" 643 | resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" 644 | 645 | faye-websocket@~0.4.3: 646 | version "0.4.4" 647 | resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.4.4.tgz#c14c5b3bf14d7417ffbfd990c0a7495cd9f337bc" 648 | 649 | figures@^1.0.1: 650 | version "1.7.0" 651 | resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" 652 | dependencies: 653 | escape-string-regexp "^1.0.5" 654 | object-assign "^4.1.0" 655 | 656 | file-sync-cmp@^0.1.0: 657 | version "0.1.1" 658 | resolved "https://registry.yarnpkg.com/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz#a5e7a8ffbfa493b43b923bbd4ca89a53b63b612b" 659 | 660 | findup-sync@^0.2.1: 661 | version "0.2.1" 662 | resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.2.1.tgz#e0a90a450075c49466ee513732057514b81e878c" 663 | dependencies: 664 | glob "~4.3.0" 665 | 666 | findup-sync@~0.1.2: 667 | version "0.1.3" 668 | resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.1.3.tgz#7f3e7a97b82392c653bf06589bd85190e93c3683" 669 | dependencies: 670 | glob "~3.2.9" 671 | lodash "~2.4.1" 672 | 673 | fs.realpath@^1.0.0: 674 | version "1.0.0" 675 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 676 | 677 | gaze@~0.5.1: 678 | version "0.5.2" 679 | resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" 680 | dependencies: 681 | globule "~0.1.0" 682 | 683 | getobject@~0.1.0: 684 | version "0.1.0" 685 | resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c" 686 | 687 | glob@5.0.x: 688 | version "5.0.15" 689 | resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" 690 | dependencies: 691 | inflight "^1.0.4" 692 | inherits "2" 693 | minimatch "2 || 3" 694 | once "^1.3.0" 695 | path-is-absolute "^1.0.0" 696 | 697 | glob@^7.0.3: 698 | version "7.1.2" 699 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 700 | dependencies: 701 | fs.realpath "^1.0.0" 702 | inflight "^1.0.4" 703 | inherits "2" 704 | minimatch "^3.0.4" 705 | once "^1.3.0" 706 | path-is-absolute "^1.0.0" 707 | 708 | glob@~3.1.21: 709 | version "3.1.21" 710 | resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" 711 | dependencies: 712 | graceful-fs "~1.2.0" 713 | inherits "1" 714 | minimatch "~0.2.11" 715 | 716 | glob@~3.2.9: 717 | version "3.2.11" 718 | resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" 719 | dependencies: 720 | inherits "2" 721 | minimatch "0.3" 722 | 723 | glob@~4.3.0: 724 | version "4.3.5" 725 | resolved "https://registry.yarnpkg.com/glob/-/glob-4.3.5.tgz#80fbb08ca540f238acce5d11d1e9bc41e75173d3" 726 | dependencies: 727 | inflight "^1.0.4" 728 | inherits "2" 729 | minimatch "^2.0.1" 730 | once "^1.3.0" 731 | 732 | globals@^9.18.0: 733 | version "9.18.0" 734 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 735 | 736 | globule@~0.1.0: 737 | version "0.1.0" 738 | resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" 739 | dependencies: 740 | glob "~3.1.21" 741 | lodash "~1.0.1" 742 | minimatch "~0.2.11" 743 | 744 | graceful-fs@~1.2.0: 745 | version "1.2.3" 746 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" 747 | 748 | "graceful-readlink@>= 1.0.0": 749 | version "1.0.1" 750 | resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" 751 | 752 | grunt-babel@~6.0.0: 753 | version "6.0.0" 754 | resolved "https://registry.yarnpkg.com/grunt-babel/-/grunt-babel-6.0.0.tgz#378189b487de1168c4c4a9fc88dd6005b35df960" 755 | dependencies: 756 | babel-core "^6.0.12" 757 | 758 | grunt-contrib-clean@~0.6.0: 759 | version "0.6.0" 760 | resolved "https://registry.yarnpkg.com/grunt-contrib-clean/-/grunt-contrib-clean-0.6.0.tgz#f532dba4b8212674c7c013e146bda6638b9048f6" 761 | dependencies: 762 | rimraf "~2.2.1" 763 | 764 | grunt-contrib-copy@~0.8.2: 765 | version "0.8.2" 766 | resolved "https://registry.yarnpkg.com/grunt-contrib-copy/-/grunt-contrib-copy-0.8.2.tgz#df31c90ffcc409bc9fafe44ec0dd1e4259916fea" 767 | dependencies: 768 | chalk "^1.1.1" 769 | file-sync-cmp "^0.1.0" 770 | 771 | grunt-contrib-uglify@~0.11.0: 772 | version "0.11.1" 773 | resolved "https://registry.yarnpkg.com/grunt-contrib-uglify/-/grunt-contrib-uglify-0.11.1.tgz#5e22a2f676cd11d871fc2a0f08aa9b2973045325" 774 | dependencies: 775 | chalk "^1.0.0" 776 | lodash "^4.0.1" 777 | maxmin "^2.0.0" 778 | uglify-js "~2.6.0" 779 | uri-path "^1.0.0" 780 | 781 | grunt-contrib-watch@^0.6.1: 782 | version "0.6.1" 783 | resolved "https://registry.yarnpkg.com/grunt-contrib-watch/-/grunt-contrib-watch-0.6.1.tgz#64fdcba25a635f5b4da1b6ce6f90da0aeb6e3f15" 784 | dependencies: 785 | async "~0.2.9" 786 | gaze "~0.5.1" 787 | lodash "~2.4.1" 788 | tiny-lr-fork "0.0.5" 789 | 790 | grunt-execute@~0.2.2: 791 | version "0.2.2" 792 | resolved "https://registry.yarnpkg.com/grunt-execute/-/grunt-execute-0.2.2.tgz#4e945fe57959cc0de7799083b6b42aed9616350a" 793 | 794 | grunt-legacy-log-utils@~0.1.1: 795 | version "0.1.1" 796 | resolved "https://registry.yarnpkg.com/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz#c0706b9dd9064e116f36f23fe4e6b048672c0f7e" 797 | dependencies: 798 | colors "~0.6.2" 799 | lodash "~2.4.1" 800 | underscore.string "~2.3.3" 801 | 802 | grunt-legacy-log@~0.1.0: 803 | version "0.1.3" 804 | resolved "https://registry.yarnpkg.com/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz#ec29426e803021af59029f87d2f9cd7335a05531" 805 | dependencies: 806 | colors "~0.6.2" 807 | grunt-legacy-log-utils "~0.1.1" 808 | hooker "~0.2.3" 809 | lodash "~2.4.1" 810 | underscore.string "~2.3.3" 811 | 812 | grunt-legacy-util@~0.2.0: 813 | version "0.2.0" 814 | resolved "https://registry.yarnpkg.com/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz#93324884dbf7e37a9ff7c026dff451d94a9e554b" 815 | dependencies: 816 | async "~0.1.22" 817 | exit "~0.1.1" 818 | getobject "~0.1.0" 819 | hooker "~0.2.3" 820 | lodash "~0.9.2" 821 | underscore.string "~2.2.1" 822 | which "~1.0.5" 823 | 824 | grunt-systemjs-builder@^0.2.5: 825 | version "0.2.7" 826 | resolved "https://registry.yarnpkg.com/grunt-systemjs-builder/-/grunt-systemjs-builder-0.2.7.tgz#e1ba74ec95dd03f7706ae2e22cf4ef0e1bd29cc9" 827 | dependencies: 828 | systemjs-builder "0.14.11 - 0.15.x" 829 | 830 | grunt@~0.4.5: 831 | version "0.4.5" 832 | resolved "https://registry.yarnpkg.com/grunt/-/grunt-0.4.5.tgz#56937cd5194324adff6d207631832a9d6ba4e7f0" 833 | dependencies: 834 | async "~0.1.22" 835 | coffee-script "~1.3.3" 836 | colors "~0.6.2" 837 | dateformat "1.0.2-1.2.3" 838 | eventemitter2 "~0.4.13" 839 | exit "~0.1.1" 840 | findup-sync "~0.1.2" 841 | getobject "~0.1.0" 842 | glob "~3.1.21" 843 | grunt-legacy-log "~0.1.0" 844 | grunt-legacy-util "~0.2.0" 845 | hooker "~0.2.3" 846 | iconv-lite "~0.2.11" 847 | js-yaml "~2.0.5" 848 | lodash "~0.9.2" 849 | minimatch "~0.2.12" 850 | nopt "~1.0.10" 851 | rimraf "~2.2.8" 852 | underscore.string "~2.2.1" 853 | which "~1.0.5" 854 | 855 | gzip-size@^3.0.0: 856 | version "3.0.0" 857 | resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-3.0.0.tgz#546188e9bdc337f673772f81660464b389dce520" 858 | dependencies: 859 | duplexer "^0.1.1" 860 | 861 | has-ansi@^2.0.0: 862 | version "2.0.0" 863 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 864 | dependencies: 865 | ansi-regex "^2.0.0" 866 | 867 | home-or-tmp@^2.0.0: 868 | version "2.0.0" 869 | resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" 870 | dependencies: 871 | os-homedir "^1.0.0" 872 | os-tmpdir "^1.0.1" 873 | 874 | hooker@~0.2.3: 875 | version "0.2.3" 876 | resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959" 877 | 878 | iconv-lite@~0.2.11: 879 | version "0.2.11" 880 | resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.2.11.tgz#1ce60a3a57864a292d1321ff4609ca4bb965adc8" 881 | 882 | inflight@^1.0.4: 883 | version "1.0.6" 884 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 885 | dependencies: 886 | once "^1.3.0" 887 | wrappy "1" 888 | 889 | inherits@1: 890 | version "1.0.2" 891 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" 892 | 893 | inherits@2: 894 | version "2.0.3" 895 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 896 | 897 | invariant@^2.2.2: 898 | version "2.2.4" 899 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" 900 | dependencies: 901 | loose-envify "^1.0.0" 902 | 903 | is-buffer@^1.1.5: 904 | version "1.1.6" 905 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 906 | 907 | is-finite@^1.0.0: 908 | version "1.0.2" 909 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 910 | dependencies: 911 | number-is-nan "^1.0.0" 912 | 913 | js-tokens@^3.0.0, js-tokens@^3.0.2: 914 | version "3.0.2" 915 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 916 | 917 | js-yaml@~2.0.5: 918 | version "2.0.5" 919 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-2.0.5.tgz#a25ae6509999e97df278c6719da11bd0687743a8" 920 | dependencies: 921 | argparse "~ 0.1.11" 922 | esprima "~ 1.0.2" 923 | 924 | jsesc@^1.3.0: 925 | version "1.3.0" 926 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" 927 | 928 | jsesc@~0.5.0: 929 | version "0.5.0" 930 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 931 | 932 | json5@^0.5.1: 933 | version "0.5.1" 934 | resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" 935 | 936 | kind-of@^3.0.2: 937 | version "3.2.2" 938 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" 939 | dependencies: 940 | is-buffer "^1.1.5" 941 | 942 | lazy-cache@^1.0.3: 943 | version "1.0.4" 944 | resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" 945 | 946 | load-grunt-tasks@~3.2.0: 947 | version "3.2.0" 948 | resolved "https://registry.yarnpkg.com/load-grunt-tasks/-/load-grunt-tasks-3.2.0.tgz#25fe7e414ba0645a752bb06f52491b422332036f" 949 | dependencies: 950 | findup-sync "^0.2.1" 951 | multimatch "^2.0.0" 952 | 953 | lodash@^4.0.1, lodash@^4.17.4: 954 | version "4.17.5" 955 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" 956 | 957 | lodash@~0.9.2: 958 | version "0.9.2" 959 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-0.9.2.tgz#8f3499c5245d346d682e5b0d3b40767e09f1a92c" 960 | 961 | lodash@~1.0.1: 962 | version "1.0.2" 963 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" 964 | 965 | lodash@~2.4.1: 966 | version "2.4.2" 967 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" 968 | 969 | lodash@~4.0.0: 970 | version "4.0.1" 971 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.0.1.tgz#cd8c902c9e03f2e69ce3e0e456d505ab89eb98f4" 972 | 973 | longest@^1.0.1: 974 | version "1.0.1" 975 | resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" 976 | 977 | loose-envify@^1.0.0: 978 | version "1.3.1" 979 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 980 | dependencies: 981 | js-tokens "^3.0.0" 982 | 983 | lru-cache@2: 984 | version "2.7.3" 985 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" 986 | 987 | maxmin@^2.0.0: 988 | version "2.1.0" 989 | resolved "https://registry.yarnpkg.com/maxmin/-/maxmin-2.1.0.tgz#4d3b220903d95eee7eb7ac7fa864e72dc09a3166" 990 | dependencies: 991 | chalk "^1.0.0" 992 | figures "^1.0.1" 993 | gzip-size "^3.0.0" 994 | pretty-bytes "^3.0.0" 995 | 996 | minimatch@0.3: 997 | version "0.3.0" 998 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" 999 | dependencies: 1000 | lru-cache "2" 1001 | sigmund "~1.0.0" 1002 | 1003 | "minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.4: 1004 | version "3.0.4" 1005 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 1006 | dependencies: 1007 | brace-expansion "^1.1.7" 1008 | 1009 | minimatch@^2.0.1: 1010 | version "2.0.10" 1011 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" 1012 | dependencies: 1013 | brace-expansion "^1.0.0" 1014 | 1015 | minimatch@~0.2.11, minimatch@~0.2.12: 1016 | version "0.2.14" 1017 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" 1018 | dependencies: 1019 | lru-cache "2" 1020 | sigmund "~1.0.0" 1021 | 1022 | minimist@0.0.8: 1023 | version "0.0.8" 1024 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 1025 | 1026 | mkdirp@^0.5.1: 1027 | version "0.5.1" 1028 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 1029 | dependencies: 1030 | minimist "0.0.8" 1031 | 1032 | ms@2.0.0: 1033 | version "2.0.0" 1034 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 1035 | 1036 | multimatch@^2.0.0: 1037 | version "2.1.0" 1038 | resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" 1039 | dependencies: 1040 | array-differ "^1.0.0" 1041 | array-union "^1.0.1" 1042 | arrify "^1.0.0" 1043 | minimatch "^3.0.0" 1044 | 1045 | next-tick@1: 1046 | version "1.0.0" 1047 | resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" 1048 | 1049 | nopt@~1.0.10: 1050 | version "1.0.10" 1051 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" 1052 | dependencies: 1053 | abbrev "1" 1054 | 1055 | nopt@~2.0.0: 1056 | version "2.0.0" 1057 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-2.0.0.tgz#ca7416f20a5e3f9c3b86180f96295fa3d0b52e0d" 1058 | dependencies: 1059 | abbrev "1" 1060 | 1061 | noptify@~0.0.3: 1062 | version "0.0.3" 1063 | resolved "https://registry.yarnpkg.com/noptify/-/noptify-0.0.3.tgz#58f654a73d9753df0c51d9686dc92104a67f4bbb" 1064 | dependencies: 1065 | nopt "~2.0.0" 1066 | 1067 | number-is-nan@^1.0.0: 1068 | version "1.0.1" 1069 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 1070 | 1071 | object-assign@^4.1.0: 1072 | version "4.1.1" 1073 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 1074 | 1075 | once@^1.3.0: 1076 | version "1.4.0" 1077 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1078 | dependencies: 1079 | wrappy "1" 1080 | 1081 | os-homedir@^1.0.0: 1082 | version "1.0.2" 1083 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 1084 | 1085 | os-tmpdir@^1.0.1: 1086 | version "1.0.2" 1087 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 1088 | 1089 | path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: 1090 | version "1.0.1" 1091 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1092 | 1093 | pretty-bytes@^3.0.0: 1094 | version "3.0.1" 1095 | resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-3.0.1.tgz#27d0008d778063a0b4811bb35c79f1bd5d5fbccf" 1096 | dependencies: 1097 | number-is-nan "^1.0.0" 1098 | 1099 | private@^0.1.6, private@^0.1.7: 1100 | version "0.1.8" 1101 | resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" 1102 | 1103 | qs@~0.5.2: 1104 | version "0.5.6" 1105 | resolved "https://registry.yarnpkg.com/qs/-/qs-0.5.6.tgz#31b1ad058567651c526921506b9a8793911a0384" 1106 | 1107 | regenerate@^1.2.1: 1108 | version "1.3.3" 1109 | resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" 1110 | 1111 | regenerator-runtime@^0.11.0: 1112 | version "0.11.1" 1113 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" 1114 | 1115 | regenerator-transform@^0.10.0: 1116 | version "0.10.1" 1117 | resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" 1118 | dependencies: 1119 | babel-runtime "^6.18.0" 1120 | babel-types "^6.19.0" 1121 | private "^0.1.6" 1122 | 1123 | regexpu-core@^2.0.0: 1124 | version "2.0.0" 1125 | resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" 1126 | dependencies: 1127 | regenerate "^1.2.1" 1128 | regjsgen "^0.2.0" 1129 | regjsparser "^0.1.4" 1130 | 1131 | regjsgen@^0.2.0: 1132 | version "0.2.0" 1133 | resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" 1134 | 1135 | regjsparser@^0.1.4: 1136 | version "0.1.5" 1137 | resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" 1138 | dependencies: 1139 | jsesc "~0.5.0" 1140 | 1141 | repeat-string@^1.5.2: 1142 | version "1.6.1" 1143 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 1144 | 1145 | repeating@^2.0.0: 1146 | version "2.0.1" 1147 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 1148 | dependencies: 1149 | is-finite "^1.0.0" 1150 | 1151 | right-align@^0.1.1: 1152 | version "0.1.3" 1153 | resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" 1154 | dependencies: 1155 | align-text "^0.1.1" 1156 | 1157 | rimraf@~2.2.1, rimraf@~2.2.8: 1158 | version "2.2.8" 1159 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" 1160 | 1161 | rollup@^0.36.3: 1162 | version "0.36.4" 1163 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.36.4.tgz#a224494c5386c1d73d38f7bb86f69f5eb011a3d2" 1164 | dependencies: 1165 | source-map-support "^0.4.0" 1166 | 1167 | rsvp@^3.0.13: 1168 | version "3.6.2" 1169 | resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" 1170 | 1171 | semver@^4.3.3: 1172 | version "4.3.6" 1173 | resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" 1174 | 1175 | sigmund@~1.0.0: 1176 | version "1.0.1" 1177 | resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" 1178 | 1179 | slash@^1.0.0: 1180 | version "1.0.0" 1181 | resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 1182 | 1183 | source-map-support@^0.4.0, source-map-support@^0.4.15: 1184 | version "0.4.18" 1185 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" 1186 | dependencies: 1187 | source-map "^0.5.6" 1188 | 1189 | source-map-support@~0.2.8: 1190 | version "0.2.10" 1191 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc" 1192 | dependencies: 1193 | source-map "0.1.32" 1194 | 1195 | source-map@0.1.32: 1196 | version "0.1.32" 1197 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266" 1198 | dependencies: 1199 | amdefine ">=0.0.4" 1200 | 1201 | source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1: 1202 | version "0.5.7" 1203 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 1204 | 1205 | strip-ansi@^3.0.0: 1206 | version "3.0.1" 1207 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1208 | dependencies: 1209 | ansi-regex "^2.0.0" 1210 | 1211 | supports-color@^2.0.0: 1212 | version "2.0.0" 1213 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 1214 | 1215 | "systemjs-builder@0.14.11 - 0.15.x": 1216 | version "0.15.36" 1217 | resolved "https://registry.yarnpkg.com/systemjs-builder/-/systemjs-builder-0.15.36.tgz#30b02372d4227cf37880f580fe67cb4edb7f1420" 1218 | dependencies: 1219 | babel-core "^6.9.0" 1220 | babel-plugin-transform-cjs-system-wrapper "^0.3.0" 1221 | babel-plugin-transform-es2015-modules-systemjs "^6.6.5" 1222 | babel-plugin-transform-global-system-wrapper "0.0.1" 1223 | babel-plugin-transform-system-register "0.0.1" 1224 | bluebird "^3.3.4" 1225 | data-uri-to-buffer "0.0.4" 1226 | es6-template-strings "^2.0.0" 1227 | glob "^7.0.3" 1228 | mkdirp "^0.5.1" 1229 | rollup "^0.36.3" 1230 | source-map "^0.5.3" 1231 | systemjs "^0.19.43" 1232 | traceur "0.0.105" 1233 | uglify-js "~2.7.5" 1234 | 1235 | systemjs@^0.19.43: 1236 | version "0.19.47" 1237 | resolved "https://registry.yarnpkg.com/systemjs/-/systemjs-0.19.47.tgz#c8c93937180f3f5481c769cd2720763fb4a31c6f" 1238 | dependencies: 1239 | when "^3.7.5" 1240 | 1241 | tiny-lr-fork@0.0.5: 1242 | version "0.0.5" 1243 | resolved "https://registry.yarnpkg.com/tiny-lr-fork/-/tiny-lr-fork-0.0.5.tgz#1e99e1e2a8469b736ab97d97eefa98c71f76ed0a" 1244 | dependencies: 1245 | debug "~0.7.0" 1246 | faye-websocket "~0.4.3" 1247 | noptify "~0.0.3" 1248 | qs "~0.5.2" 1249 | 1250 | to-fast-properties@^1.0.3: 1251 | version "1.0.3" 1252 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" 1253 | 1254 | traceur@0.0.105: 1255 | version "0.0.105" 1256 | resolved "https://registry.yarnpkg.com/traceur/-/traceur-0.0.105.tgz#5cf9dee83d6b77861c3d6c44d53859aed7ab0479" 1257 | dependencies: 1258 | commander "2.9.x" 1259 | glob "5.0.x" 1260 | rsvp "^3.0.13" 1261 | semver "^4.3.3" 1262 | source-map-support "~0.2.8" 1263 | 1264 | trim-right@^1.0.1: 1265 | version "1.0.1" 1266 | resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" 1267 | 1268 | uglify-js@~2.6.0: 1269 | version "2.6.4" 1270 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.6.4.tgz#65ea2fb3059c9394692f15fed87c2b36c16b9adf" 1271 | dependencies: 1272 | async "~0.2.6" 1273 | source-map "~0.5.1" 1274 | uglify-to-browserify "~1.0.0" 1275 | yargs "~3.10.0" 1276 | 1277 | uglify-js@~2.7.5: 1278 | version "2.7.5" 1279 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" 1280 | dependencies: 1281 | async "~0.2.6" 1282 | source-map "~0.5.1" 1283 | uglify-to-browserify "~1.0.0" 1284 | yargs "~3.10.0" 1285 | 1286 | uglify-to-browserify@~1.0.0: 1287 | version "1.0.2" 1288 | resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" 1289 | 1290 | underscore.string@~2.2.1: 1291 | version "2.2.1" 1292 | resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.2.1.tgz#d7c0fa2af5d5a1a67f4253daee98132e733f0f19" 1293 | 1294 | underscore.string@~2.3.3: 1295 | version "2.3.3" 1296 | resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.3.3.tgz#71c08bf6b428b1133f37e78fa3a21c82f7329b0d" 1297 | 1298 | underscore.string@~2.4.0: 1299 | version "2.4.0" 1300 | resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.4.0.tgz#8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b" 1301 | 1302 | underscore@~1.7.0: 1303 | version "1.7.0" 1304 | resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" 1305 | 1306 | uri-path@^1.0.0: 1307 | version "1.0.0" 1308 | resolved "https://registry.yarnpkg.com/uri-path/-/uri-path-1.0.0.tgz#9747f018358933c31de0fccfd82d138e67262e32" 1309 | 1310 | when@^3.7.5: 1311 | version "3.7.8" 1312 | resolved "https://registry.yarnpkg.com/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82" 1313 | 1314 | which@~1.0.5: 1315 | version "1.0.9" 1316 | resolved "https://registry.yarnpkg.com/which/-/which-1.0.9.tgz#460c1da0f810103d0321a9b633af9e575e64486f" 1317 | 1318 | window-size@0.1.0: 1319 | version "0.1.0" 1320 | resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" 1321 | 1322 | wordwrap@0.0.2: 1323 | version "0.0.2" 1324 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" 1325 | 1326 | wrappy@1: 1327 | version "1.0.2" 1328 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1329 | 1330 | yargs@~3.10.0: 1331 | version "3.10.0" 1332 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" 1333 | dependencies: 1334 | camelcase "^1.0.2" 1335 | cliui "^2.1.0" 1336 | decamelize "^1.0.0" 1337 | window-size "0.1.0" 1338 | --------------------------------------------------------------------------------