mirror of
https://github.com/nasa/openmct.git
synced 2025-06-06 09:21:43 +00:00
Merge branch 'master' of https://github.com/nasa/openmct into fix-tutorial
PR is also addresses #1206
This commit is contained in:
commit
1f6ca8bcc3
@ -19,7 +19,6 @@
|
|||||||
"comma-separated-values": "^3.6.4",
|
"comma-separated-values": "^3.6.4",
|
||||||
"FileSaver.js": "^0.0.2",
|
"FileSaver.js": "^0.0.2",
|
||||||
"zepto": "^1.1.6",
|
"zepto": "^1.1.6",
|
||||||
"html2canvas": "^0.4.1",
|
"html2canvas": "^0.4.1"
|
||||||
"jspdf": "^1.2.61"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
4
main.js
4
main.js
@ -29,7 +29,6 @@ requirejs.config({
|
|||||||
"csv": "bower_components/comma-separated-values/csv.min",
|
"csv": "bower_components/comma-separated-values/csv.min",
|
||||||
"es6-promise": "bower_components/es6-promise/es6-promise.min",
|
"es6-promise": "bower_components/es6-promise/es6-promise.min",
|
||||||
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
|
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
|
||||||
"jsPDF": "bower_components/jspdf/dist/jspdf.min",
|
|
||||||
"moment": "bower_components/moment/moment",
|
"moment": "bower_components/moment/moment",
|
||||||
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
||||||
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
||||||
@ -48,9 +47,6 @@ requirejs.config({
|
|||||||
"html2canvas": {
|
"html2canvas": {
|
||||||
"exports": "html2canvas"
|
"exports": "html2canvas"
|
||||||
},
|
},
|
||||||
"jsPDF": {
|
|
||||||
"exports": "jsPDF"
|
|
||||||
},
|
|
||||||
"moment-duration-format": {
|
"moment-duration-format": {
|
||||||
"deps": ["moment"]
|
"deps": ["moment"]
|
||||||
},
|
},
|
||||||
|
@ -245,7 +245,9 @@ define([
|
|||||||
"key": "cancel",
|
"key": "cancel",
|
||||||
"category": "conclude-editing",
|
"category": "conclude-editing",
|
||||||
"implementation": CancelAction,
|
"implementation": CancelAction,
|
||||||
"name": "Cancel",
|
// Because we use the name as label for edit buttons and mct-control buttons need
|
||||||
|
// the label to be set to undefined in order to not apply the labeled CSS rule.
|
||||||
|
"name": undefined,
|
||||||
"cssclass": "icon-x no-label",
|
"cssclass": "icon-x no-label",
|
||||||
"description": "Discard changes made to these objects.",
|
"description": "Discard changes made to these objects.",
|
||||||
"depends": []
|
"depends": []
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<mct-control key="'button'"
|
<mct-control key="'button'"
|
||||||
structure="{
|
structure="{
|
||||||
text: saveActions[0].getMetadata().name,
|
text: saveActions[0].getMetadata().name,
|
||||||
click: saveActions[0].perform,
|
click: actionPerformer(saveActions[0]),
|
||||||
cssclass: 'major ' + saveActions[0].getMetadata().cssclass
|
cssclass: 'major ' + saveActions[0].getMetadata().cssclass
|
||||||
}">
|
}">
|
||||||
</mct-control>
|
</mct-control>
|
||||||
@ -42,11 +42,12 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span ng-repeat="currentAction in otherEditActions">
|
<span ng-repeat="currentAction in otherEditActions">
|
||||||
<a class='s-button {{currentAction.getMetadata().cssclass}}'
|
<mct-control key="'button'"
|
||||||
title='{{currentAction.getMetadata().name}}'
|
structure="{
|
||||||
ng-click="currentAction.perform()"
|
text: currentAction.getMetadata().name,
|
||||||
ng-class="{ major: $index === 0 && saveActions.length === 0 }">
|
click: actionPerformer(currentAction),
|
||||||
<span class="title-label">{{currentAction.getMetadata().name}}</span>
|
cssclass: currentAction.getMetadata().cssclass
|
||||||
</a>
|
}">
|
||||||
|
</mct-control>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
@ -61,6 +61,12 @@ define(
|
|||||||
$scope.otherEditActions = $scope.action ?
|
$scope.otherEditActions = $scope.action ?
|
||||||
$scope.action.getActions(OTHERS_ACTION_CONTEXT) :
|
$scope.action.getActions(OTHERS_ACTION_CONTEXT) :
|
||||||
[];
|
[];
|
||||||
|
|
||||||
|
// Required because Angular does not allow 'bind'
|
||||||
|
// in expressions.
|
||||||
|
$scope.actionPerformer = function (action) {
|
||||||
|
return action.perform.bind(action);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update set of actions whenever the action capability
|
// Update set of actions whenever the action capability
|
||||||
|
@ -216,6 +216,7 @@ input[type="search"] {
|
|||||||
.l-input-lg input[type="text"] { width: 100% !important; }
|
.l-input-lg input[type="text"] { width: 100% !important; }
|
||||||
.l-input-med input[type="text"] { width: 200px !important; }
|
.l-input-med input[type="text"] { width: 200px !important; }
|
||||||
.l-input-sm input[type="text"] { width: 50px !important; }
|
.l-input-sm input[type="text"] { width: 50px !important; }
|
||||||
|
.l-textarea-sm textarea { position: relative; height: 50px; }
|
||||||
.l-numeric input[type="text"] { text-align: right; }
|
.l-numeric input[type="text"] { text-align: right; }
|
||||||
|
|
||||||
.input-labeled {
|
.input-labeled {
|
||||||
|
@ -252,6 +252,14 @@ define([
|
|||||||
"pattern": "\\S+",
|
"pattern": "\\S+",
|
||||||
"required": true,
|
"required": true,
|
||||||
"cssclass": "l-input-lg"
|
"cssclass": "l-input-lg"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Notes",
|
||||||
|
"key": "notes",
|
||||||
|
"property": "notes",
|
||||||
|
"control": "textarea",
|
||||||
|
"required": false,
|
||||||
|
"cssclass": "l-textarea-sm"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -146,16 +146,6 @@ define([
|
|||||||
"copyright": "Copyright © 2012 Niklas von Hertzen.",
|
"copyright": "Copyright © 2012 Niklas von Hertzen.",
|
||||||
"license": "license-mit",
|
"license": "license-mit",
|
||||||
"link": "https://github.com/niklasvh/html2canvas/blob/master/LICENSE"
|
"link": "https://github.com/niklasvh/html2canvas/blob/master/LICENSE"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "jsPDF",
|
|
||||||
"version": "1.2.61",
|
|
||||||
"author": "James Hall",
|
|
||||||
"description": "JavaScript HTML renderer",
|
|
||||||
"website": "https://github.com/MrRio/jsPDF",
|
|
||||||
"copyright": "Copyright © 2010-2016 James Hall",
|
|
||||||
"license": "license-mit",
|
|
||||||
"link": "https://github.com/MrRio/jsPDF/blob/master/MIT-LICENSE.txt"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,6 @@
|
|||||||
class="abs holder holder-plot has-control-bar">
|
class="abs holder holder-plot has-control-bar">
|
||||||
<div class="l-control-bar" ng-show="!plot.hideExportButtons">
|
<div class="l-control-bar" ng-show="!plot.hideExportButtons">
|
||||||
<span class="l-btn-set">
|
<span class="l-btn-set">
|
||||||
<a class="s-button t-export icon-download labeled first"
|
|
||||||
ng-click="plot.exportPDF()"
|
|
||||||
title="Export This View's Data as PDF">
|
|
||||||
PDF
|
|
||||||
</a>
|
|
||||||
<a class="s-button t-export labeled"
|
<a class="s-button t-export labeled"
|
||||||
ng-click="plot.exportPNG()"
|
ng-click="plot.exportPNG()"
|
||||||
title="Export This View's Data as PNG">
|
title="Export This View's Data as PNG">
|
||||||
|
@ -368,17 +368,6 @@ define(
|
|||||||
return this.pending;
|
return this.pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Export the plot to PDF
|
|
||||||
*/
|
|
||||||
PlotController.prototype.exportPDF = function () {
|
|
||||||
var self = this;
|
|
||||||
self.hideExportButtons = true;
|
|
||||||
self.exportImageService.exportPDF(self.$element[0], "plot.pdf").finally(function () {
|
|
||||||
self.hideExportButtons = false;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export the plot to PNG
|
* Export the plot to PNG
|
||||||
*/
|
*/
|
||||||
|
@ -26,32 +26,29 @@
|
|||||||
define(
|
define(
|
||||||
[
|
[
|
||||||
"html2canvas",
|
"html2canvas",
|
||||||
"jsPDF",
|
|
||||||
"saveAs"
|
"saveAs"
|
||||||
],
|
],
|
||||||
function (
|
function (
|
||||||
html2canvas,
|
html2canvas,
|
||||||
jsPDF,
|
|
||||||
saveAs
|
saveAs
|
||||||
) {
|
) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The export image service will export any HTML node to
|
* The export image service will export any HTML node to
|
||||||
* PDF, JPG, or PNG.
|
* JPG, or PNG.
|
||||||
* @param {object} $q
|
* @param {object} $q
|
||||||
* @param {object} $timeout
|
* @param {object} $timeout
|
||||||
* @param {object} $log
|
* @param {object} $log
|
||||||
* @param {constant} EXPORT_IMAGE_TIMEOUT time in milliseconds before a timeout error is returned
|
* @param {constant} EXPORT_IMAGE_TIMEOUT time in milliseconds before a timeout error is returned
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function ExportImageService($q, $timeout, $log, EXPORT_IMAGE_TIMEOUT, injHtml2Canvas, injJsPDF, injSaveAs, injFileReader) {
|
function ExportImageService($q, $timeout, $log, EXPORT_IMAGE_TIMEOUT, injHtml2Canvas, injSaveAs, injFileReader) {
|
||||||
self.$q = $q;
|
self.$q = $q;
|
||||||
self.$timeout = $timeout;
|
self.$timeout = $timeout;
|
||||||
self.$log = $log;
|
self.$log = $log;
|
||||||
self.EXPORT_IMAGE_TIMEOUT = EXPORT_IMAGE_TIMEOUT;
|
self.EXPORT_IMAGE_TIMEOUT = EXPORT_IMAGE_TIMEOUT;
|
||||||
self.html2canvas = injHtml2Canvas || html2canvas;
|
self.html2canvas = injHtml2Canvas || html2canvas;
|
||||||
self.jsPDF = injJsPDF || jsPDF;
|
|
||||||
self.saveAs = injSaveAs || saveAs;
|
self.saveAs = injSaveAs || saveAs;
|
||||||
self.reader = injFileReader || new FileReader();
|
self.reader = injFileReader || new FileReader();
|
||||||
}
|
}
|
||||||
@ -128,23 +125,6 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes a screenshot of a DOM node and exports to PDF.
|
|
||||||
* @param {node} element to be exported
|
|
||||||
* @param {string} filename the exported image
|
|
||||||
* @returns {promise}
|
|
||||||
*/
|
|
||||||
ExportImageService.prototype.exportPDF = function (element, filename) {
|
|
||||||
return renderElement(element, "jpeg").then(function (img) {
|
|
||||||
self.reader.readAsDataURL(img);
|
|
||||||
self.reader.onloadend = function () {
|
|
||||||
var pdf = new self.jsPDF("l", "px", [element.offsetHeight, element.offsetWidth]);
|
|
||||||
pdf.addImage(self.reader.result, "JPEG", 0, 0, element.offsetWidth, element.offsetHeight);
|
|
||||||
pdf.save(filename);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a screenshot of a DOM node and exports to JPG.
|
* Takes a screenshot of a DOM node and exports to JPG.
|
||||||
* @param {node} element to be exported
|
* @param {node} element to be exported
|
||||||
|
@ -72,7 +72,7 @@ define(
|
|||||||
mockElement = angular.element('<div />');
|
mockElement = angular.element('<div />');
|
||||||
mockExportImageService = jasmine.createSpyObj(
|
mockExportImageService = jasmine.createSpyObj(
|
||||||
"ExportImageService",
|
"ExportImageService",
|
||||||
["exportJPG", "exportPNG", "exportPDF"]
|
["exportJPG", "exportPNG"]
|
||||||
);
|
);
|
||||||
mockFormatter = jasmine.createSpyObj(
|
mockFormatter = jasmine.createSpyObj(
|
||||||
"formatter",
|
"formatter",
|
||||||
|
@ -33,8 +33,6 @@ define(
|
|||||||
mockLog,
|
mockLog,
|
||||||
mockHtml2Canvas,
|
mockHtml2Canvas,
|
||||||
mockCanvas,
|
mockCanvas,
|
||||||
mockJsPDF,
|
|
||||||
mockJsPDFSave,
|
|
||||||
mockSaveAs,
|
mockSaveAs,
|
||||||
mockFileReader,
|
mockFileReader,
|
||||||
mockExportTimeoutConstant,
|
mockExportTimeoutConstant,
|
||||||
@ -79,13 +77,6 @@ define(
|
|||||||
"canvas",
|
"canvas",
|
||||||
["toBlob"]
|
["toBlob"]
|
||||||
);
|
);
|
||||||
mockJsPDFSave = jasmine.createSpy("jsPDFSave");
|
|
||||||
mockJsPDF = function () {
|
|
||||||
return {
|
|
||||||
"addImage": function () {},
|
|
||||||
"save": mockJsPDFSave
|
|
||||||
};
|
|
||||||
};
|
|
||||||
mockSaveAs = jasmine.createSpy("saveAs");
|
mockSaveAs = jasmine.createSpy("saveAs");
|
||||||
mockFileReader = jasmine.createSpyObj(
|
mockFileReader = jasmine.createSpyObj(
|
||||||
"FileReader",
|
"FileReader",
|
||||||
@ -100,23 +91,11 @@ define(
|
|||||||
mockLog,
|
mockLog,
|
||||||
mockExportTimeoutConstant,
|
mockExportTimeoutConstant,
|
||||||
mockHtml2Canvas,
|
mockHtml2Canvas,
|
||||||
mockJsPDF,
|
|
||||||
mockSaveAs,
|
mockSaveAs,
|
||||||
mockFileReader
|
mockFileReader
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("runs html2canvas and tries to save a pdf", function () {
|
|
||||||
exportImageService.exportPDF(testElement, "plot.pdf");
|
|
||||||
mockFileReader.onloadend();
|
|
||||||
|
|
||||||
expect(mockHtml2Canvas).toHaveBeenCalledWith(testElement, { onrendered: jasmine.any(Function) });
|
|
||||||
expect(mockCanvas.toBlob).toHaveBeenCalledWith(mockDeferred.resolve, "image/jpeg");
|
|
||||||
expect(mockDeferred.reject).not.toHaveBeenCalled();
|
|
||||||
expect(mockJsPDFSave).toHaveBeenCalled();
|
|
||||||
expect(mockPromise.finally).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("runs html2canvas and tries to save a png", function () {
|
it("runs html2canvas and tries to save a png", function () {
|
||||||
exportImageService.exportPNG(testElement, "plot.png");
|
exportImageService.exportPNG(testElement, "plot.png");
|
||||||
|
|
||||||
|
@ -182,6 +182,16 @@ define([
|
|||||||
"capacity"
|
"capacity"
|
||||||
],
|
],
|
||||||
"pattern": "^-?\\d+(\\.\\d*)?$"
|
"pattern": "^-?\\d+(\\.\\d*)?$"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Battery starting SOC (%)",
|
||||||
|
"control": "textfield",
|
||||||
|
"required": false,
|
||||||
|
"conversion": "number",
|
||||||
|
"property": [
|
||||||
|
"startingSOC"
|
||||||
|
],
|
||||||
|
"pattern": "^([0-9](\\.\\d*)?|[1-9][0-9](\\.\\d*)?|100)%?$"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"model": {
|
"model": {
|
||||||
|
@ -37,7 +37,8 @@ define(
|
|||||||
// Build graphs for this group of utilizations
|
// Build graphs for this group of utilizations
|
||||||
function buildGraphs(utilizations) {
|
function buildGraphs(utilizations) {
|
||||||
var utilizationMap = {},
|
var utilizationMap = {},
|
||||||
result = {};
|
result = {},
|
||||||
|
startingSOC;
|
||||||
|
|
||||||
// Bucket utilizations by type
|
// Bucket utilizations by type
|
||||||
utilizations.forEach(function (u) {
|
utilizations.forEach(function (u) {
|
||||||
@ -55,12 +56,14 @@ define(
|
|||||||
if (domainObject.getModel().type === 'timeline' &&
|
if (domainObject.getModel().type === 'timeline' &&
|
||||||
result.power &&
|
result.power &&
|
||||||
domainObject.getModel().capacity > 0) {
|
domainObject.getModel().capacity > 0) {
|
||||||
|
startingSOC = isNaN(parseFloat(domainObject.getModel().startingSOC)) ?
|
||||||
|
100 : parseFloat(domainObject.getModel().startingSOC);
|
||||||
|
|
||||||
result.battery = new CumulativeGraph(
|
result.battery = new CumulativeGraph(
|
||||||
result.power,
|
result.power,
|
||||||
0,
|
0,
|
||||||
domainObject.getModel().capacity, // Watts
|
domainObject.getModel().capacity, // Watts
|
||||||
domainObject.getModel().capacity,
|
(startingSOC / 100) * domainObject.getModel().capacity,
|
||||||
1 / 3600000 // millis-to-hour (since units are watt-hours)
|
1 / 3600000 // millis-to-hour (since units are watt-hours)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,7 @@ define(
|
|||||||
it("provides a battery graph for timelines with capacity", function () {
|
it("provides a battery graph for timelines with capacity", function () {
|
||||||
var mockCallback = jasmine.createSpy('callback');
|
var mockCallback = jasmine.createSpy('callback');
|
||||||
testModel.capacity = 1000;
|
testModel.capacity = 1000;
|
||||||
|
testModel.startingSOC = 100;
|
||||||
testModel.type = "timeline";
|
testModel.type = "timeline";
|
||||||
mockDomainObject.useCapability.andReturn(asPromise([
|
mockDomainObject.useCapability.andReturn(asPromise([
|
||||||
{ key: "power", start: 0, end: 15 }
|
{ key: "power", start: 0, end: 15 }
|
||||||
|
@ -32,6 +32,7 @@ define([
|
|||||||
"text!./res/templates/controls/datetime.html",
|
"text!./res/templates/controls/datetime.html",
|
||||||
"text!./res/templates/controls/select.html",
|
"text!./res/templates/controls/select.html",
|
||||||
"text!./res/templates/controls/textfield.html",
|
"text!./res/templates/controls/textfield.html",
|
||||||
|
"text!./res/templates/controls/textarea.html",
|
||||||
"text!./res/templates/controls/button.html",
|
"text!./res/templates/controls/button.html",
|
||||||
"text!./res/templates/controls/color.html",
|
"text!./res/templates/controls/color.html",
|
||||||
"text!./res/templates/controls/composite.html",
|
"text!./res/templates/controls/composite.html",
|
||||||
@ -51,6 +52,7 @@ define([
|
|||||||
datetimeTemplate,
|
datetimeTemplate,
|
||||||
selectTemplate,
|
selectTemplate,
|
||||||
textfieldTemplate,
|
textfieldTemplate,
|
||||||
|
textareaTemplate,
|
||||||
buttonTemplate,
|
buttonTemplate,
|
||||||
colorTemplate,
|
colorTemplate,
|
||||||
compositeTemplate,
|
compositeTemplate,
|
||||||
@ -103,6 +105,10 @@ define([
|
|||||||
"key": "textfield",
|
"key": "textfield",
|
||||||
"template": textfieldTemplate
|
"template": textfieldTemplate
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"key": "textarea",
|
||||||
|
"template": textareaTemplate
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"key": "button",
|
"key": "button",
|
||||||
"template": buttonTemplate
|
"template": buttonTemplate
|
||||||
|
31
platform/forms/res/templates/controls/textarea.html
Normal file
31
platform/forms/res/templates/controls/textarea.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!--
|
||||||
|
Open MCT, Copyright (c) 2014-2016, United States Government
|
||||||
|
as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
Administration. All rights reserved.
|
||||||
|
|
||||||
|
Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
Open MCT includes source code licensed under additional open source
|
||||||
|
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
this source code distribution or the Licensing information page available
|
||||||
|
at runtime from the About dialog for additional information.
|
||||||
|
-->
|
||||||
|
<span class='form-control shell'>
|
||||||
|
<span class='field control {{structure.cssclass}}'>
|
||||||
|
<textarea ng-required="ngRequired"
|
||||||
|
ng-model="ngModel[field]"
|
||||||
|
ng-pattern="ngPattern"
|
||||||
|
size="{{structure.size}}"
|
||||||
|
name="mctControl">
|
||||||
|
</textarea>
|
||||||
|
</span>
|
||||||
|
</span>
|
@ -55,7 +55,6 @@ requirejs.config({
|
|||||||
"csv": "bower_components/comma-separated-values/csv.min",
|
"csv": "bower_components/comma-separated-values/csv.min",
|
||||||
"es6-promise": "bower_components/es6-promise/es6-promise.min",
|
"es6-promise": "bower_components/es6-promise/es6-promise.min",
|
||||||
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
|
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
|
||||||
"jsPDF": "bower_components/jspdf/dist/jspdf.min",
|
|
||||||
"moment": "bower_components/moment/moment",
|
"moment": "bower_components/moment/moment",
|
||||||
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
|
||||||
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user