Launch Week Day 5: Introducing Reachability for PHP.Learn More
Socket
Book a DemoSign in
Socket

videojs-contrib-dash

Package Overview
Dependencies
Maintainers
4
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

videojs-contrib-dash - npm Package Compare versions

Comparing version
1.0.2
to
1.1.0
+4
-115
dist/videojs-dash.js

@@ -1,2 +0,2 @@

/*! videojs-contrib-dash - v1.0.2 - 2015-07-23
/*! videojs-contrib-dash - v1.1.0 - 2015-07-24
* Copyright (c) 2015 Brightcove */

@@ -69,3 +69,5 @@ (function(window, videojs) {

// injection
Html5DashJS.useVideoJSDebug(videojs);
if (Html5DashJS.useVideoJSDebug) {
Html5DashJS.useVideoJSDebug(videojs);
}

@@ -123,115 +125,2 @@ // Save the context after the first initialization for subsequent instances

/*
* Change MediaPlayer.utils.Debug to log using videojs debugger in order to
* keep the console.log clean
*/
Html5DashJS.useVideoJSDebug = function (videojs) {
if (Html5DashJS.originalDebug) {
return;
}
if (videojs && videojs.log && videojs.log.debug) {
Html5DashJS.originalDebug = MediaPlayer.utils.Debug;
// Replace the global Debug function in Dash.js
MediaPlayer.utils.Debug = function () {
var logToBrowserConsole = true,
showLogTimestamp = false,
showCalleeName = false,
startTime = new Date().getTime(),
eventBus;
return {
system: undefined,
eventBus: undefined,
setup: function() {
this.system.mapValue('log', this.log);
eventBus = this.eventBus;
},
/**
* Prepends a timestamp in milliseconds to each log message.
* @param {boolean} value Set to true if you want to see a timestamp in each log message
* @default false
* @memberof MediaPlayer.utils.Debug#
*/
setLogTimestampVisible: function(value) {
showLogTimestamp = value;
},
/**
* Prepends the callee object name, and media type if available, to each log message.
* @param {boolean} value Set to true if you want to see a object name and media type in
* each log message.
* @default false
* @memberof MediaPlayer.utils.Debug#
*/
showCalleeName: function(value) {
showCalleeName = value;
},
/**
* Toggles logging to the browser's javascript console. If you set to false you will
* still receive a log event with the same message.
* @param {boolean} value Set to false if you want to turn off logging to the browser's
* console.
* @default true
* @memberof MediaPlayer.utils.Debug#
*/
setLogToBrowserConsole: function(value) {
logToBrowserConsole = value;
},
/**
* Use this method to get the state of logToBrowserConsole.
* @returns {boolean} The current value of logToBrowserConsole
* @memberof MediaPlayer.utils.Debug#
*/
getLogToBrowserConsole: function() {
return logToBrowserConsole;
},
/**
* This method will allow you send log messages to either the browser's console and/or
* dispatch an event to capture at the media player level.
* @param arguments The message you want to log. The Arguments object is supported for
* this method so you can send in comma separated logging items.
* @memberof MediaPlayer.utils.Debug#
*/
log: function () {
var message = '',
logTime = null;
if (showLogTimestamp) {
logTime = new Date().getTime();
message += '[' + (logTime - startTime) + ']';
}
if (showCalleeName && this.getName) {
message += '[' + this.getName() + ']';
}
if (this.getMediaType && this.getMediaType()) {
message += '[' + this.getMediaType() + ']';
}
if (message.length > 0) {
message += ' ';
}
Array.apply(null, arguments).forEach(function(item) {
message += item + ' ';
});
if (logToBrowserConsole) {
videojs.log.debug(message);
}
eventBus.dispatchEvent({
type: 'log',
message: message
});
}
};
};
}
};
/*
* Add a css-class that is used to temporarily hide the error dialog while so that

@@ -238,0 +127,0 @@ * we don't see a flash of the dialog box when we remove the video element's src

+2
-2

@@ -1,3 +0,3 @@

/*! videojs-contrib-dash - v1.0.2 - 2015-07-23
/*! videojs-contrib-dash - v1.1.0 - 2015-07-24
* Copyright (c) 2015 Brightcove */
!function(a,b){"use strict";function c(a,d){var e,f=d.options();this.tech_=d,this.el_=d.el(),this.elParent_=this.el_.parentNode,a.src&&(d.isReady_=!1,e=a.src,this.keySystemOptions_=c.buildDashJSProtData(a.keySystemOptions),c.hideErrors(this.elParent_),c.useVideoJSDebug(b),c.context_=c.context_||new Dash.di.DashContext,this.mediaPlayer_=new MediaPlayer(c.context_),this.mediaPlayer_.startup(),this.mediaPlayer_.attachView(this.el_),f.autoplay||this.mediaPlayer_.setAutoPlay(!1),this.mediaPlayer_.retrieveManifest(e,b.bind(this,this.initializeDashJS)))}var d=function(a){return"[object Array]"===Object.prototype.toString.call(a)},e=function(a){return"[object Object]"===Object.prototype.toString.call(a)},f=function(a,b){var c,d,g,h;h={};for(c in b)b.hasOwnProperty(c)&&(d=a[c],g=b[c],e(d)&&e(g)?a[c]=f(d,g):a[c]=b[c]);return a};c.prototype.initializeDashJS=function(a,d){var e={};return d?(c.showErrors(this.elParent_),this.tech_.triggerReady(),void this.dispose()):(c.getWidevineProtectionData&&(e=c.getWidevineProtectionData(a),this.keySystemOptions_=f(this.keySystemOptions_,e)),void this.resetSrc_(b.bind(this,function(){c.showErrors(this.elParent_),this.mediaPlayer_.attachSource(a,null,this.keySystemOptions_),this.tech_.triggerReady()})))},c.useVideoJSDebug=function(a){c.originalDebug||a&&a.log&&a.log.debug&&(c.originalDebug=MediaPlayer.utils.Debug,MediaPlayer.utils.Debug=function(){var b,c=!0,d=!1,e=!1,f=(new Date).getTime();return{system:void 0,eventBus:void 0,setup:function(){this.system.mapValue("log",this.log),b=this.eventBus},setLogTimestampVisible:function(a){d=a},showCalleeName:function(a){e=a},setLogToBrowserConsole:function(a){c=a},getLogToBrowserConsole:function(){return c},log:function(){var g="",h=null;d&&(h=(new Date).getTime(),g+="["+(h-f)+"]"),e&&this.getName&&(g+="["+this.getName()+"]"),this.getMediaType&&this.getMediaType()&&(g+="["+this.getMediaType()+"]"),g.length>0&&(g+=" "),Array.apply(null,arguments).forEach(function(a){g+=a+" "}),c&&a.log.debug(g),b.dispatchEvent({type:"log",message:g})}}})},c.hideErrors=function(a){a.className+="vjs-dashjs-hide-errors"},c.showErrors=function(a){setTimeout(function(){a.className=a.className.replace("vjs-dashjs-hide-errors","")},250)},c.buildDashJSProtData=function(a){var b,c,e,g={};if(!a||!d(a))return g;for(e=0;e<a.length;e++)b=a[e],c=f({},b.options),c.licenseUrl&&(c.laURL=c.licenseUrl,delete c.licenseUrl),g[b.name]=c;return g},c.prototype.resetSrc_=function(a){this.el_&&(this.el_.src="",this.el_.setMediaKeys?this.el_.setMediaKeys(null).then(a,a):a())},c.prototype.dispose=function(){this.mediaPlayer_&&this.mediaPlayer_.reset(),this.resetSrc_(function(){})},a.MediaSource&&b.Html5.registerSourceHandler({canHandleSource:function(a){var b=/^application\/dash\+xml/i,c=/\.mpd/i;return b.test(a.type)?"probably":c.test(a.src)?"maybe":""},handleSource:function(a,b){return new c(a,b)}}),b.Html5DashJS=c}(window,window.videojs);
!function(a,b){"use strict";function c(a,d){var e,f=d.options();this.tech_=d,this.el_=d.el(),this.elParent_=this.el_.parentNode,a.src&&(d.isReady_=!1,e=a.src,this.keySystemOptions_=c.buildDashJSProtData(a.keySystemOptions),c.hideErrors(this.elParent_),c.useVideoJSDebug&&c.useVideoJSDebug(b),c.context_=c.context_||new Dash.di.DashContext,this.mediaPlayer_=new MediaPlayer(c.context_),this.mediaPlayer_.startup(),this.mediaPlayer_.attachView(this.el_),f.autoplay||this.mediaPlayer_.setAutoPlay(!1),this.mediaPlayer_.retrieveManifest(e,b.bind(this,this.initializeDashJS)))}var d=function(a){return"[object Array]"===Object.prototype.toString.call(a)},e=function(a){return"[object Object]"===Object.prototype.toString.call(a)},f=function(a,b){var c,d,g,h;h={};for(c in b)b.hasOwnProperty(c)&&(d=a[c],g=b[c],e(d)&&e(g)?a[c]=f(d,g):a[c]=b[c]);return a};c.prototype.initializeDashJS=function(a,d){var e={};return d?(c.showErrors(this.elParent_),this.tech_.triggerReady(),void this.dispose()):(c.getWidevineProtectionData&&(e=c.getWidevineProtectionData(a),this.keySystemOptions_=f(this.keySystemOptions_,e)),void this.resetSrc_(b.bind(this,function(){c.showErrors(this.elParent_),this.mediaPlayer_.attachSource(a,null,this.keySystemOptions_),this.tech_.triggerReady()})))},c.hideErrors=function(a){a.className+="vjs-dashjs-hide-errors"},c.showErrors=function(a){setTimeout(function(){a.className=a.className.replace("vjs-dashjs-hide-errors","")},250)},c.buildDashJSProtData=function(a){var b,c,e,g={};if(!a||!d(a))return g;for(e=0;e<a.length;e++)b=a[e],c=f({},b.options),c.licenseUrl&&(c.laURL=c.licenseUrl,delete c.licenseUrl),g[b.name]=c;return g},c.prototype.resetSrc_=function(a){this.el_&&(this.el_.src="",this.el_.setMediaKeys?this.el_.setMediaKeys(null).then(a,a):a())},c.prototype.dispose=function(){this.mediaPlayer_&&this.mediaPlayer_.reset(),this.resetSrc_(function(){})},a.MediaSource&&b.Html5.registerSourceHandler({canHandleSource:function(a){var b=/^application\/dash\+xml/i,c=/\.mpd/i;return b.test(a.type)?"probably":c.test(a.src)?"maybe":""},handleSource:function(a,b){return new c(a,b)}}),b.Html5DashJS=c}(window,window.videojs);

@@ -8,3 +8,3 @@ {

},
"version": "1.0.2",
"version": "1.1.0",
"author": {

@@ -11,0 +11,0 @@ "name": "Brightcove"

@@ -67,3 +67,5 @@ (function(window, videojs) {

// injection
Html5DashJS.useVideoJSDebug(videojs);
if (Html5DashJS.useVideoJSDebug) {
Html5DashJS.useVideoJSDebug(videojs);
}

@@ -121,115 +123,2 @@ // Save the context after the first initialization for subsequent instances

/*
* Change MediaPlayer.utils.Debug to log using videojs debugger in order to
* keep the console.log clean
*/
Html5DashJS.useVideoJSDebug = function (videojs) {
if (Html5DashJS.originalDebug) {
return;
}
if (videojs && videojs.log && videojs.log.debug) {
Html5DashJS.originalDebug = MediaPlayer.utils.Debug;
// Replace the global Debug function in Dash.js
MediaPlayer.utils.Debug = function () {
var logToBrowserConsole = true,
showLogTimestamp = false,
showCalleeName = false,
startTime = new Date().getTime(),
eventBus;
return {
system: undefined,
eventBus: undefined,
setup: function() {
this.system.mapValue('log', this.log);
eventBus = this.eventBus;
},
/**
* Prepends a timestamp in milliseconds to each log message.
* @param {boolean} value Set to true if you want to see a timestamp in each log message
* @default false
* @memberof MediaPlayer.utils.Debug#
*/
setLogTimestampVisible: function(value) {
showLogTimestamp = value;
},
/**
* Prepends the callee object name, and media type if available, to each log message.
* @param {boolean} value Set to true if you want to see a object name and media type in
* each log message.
* @default false
* @memberof MediaPlayer.utils.Debug#
*/
showCalleeName: function(value) {
showCalleeName = value;
},
/**
* Toggles logging to the browser's javascript console. If you set to false you will
* still receive a log event with the same message.
* @param {boolean} value Set to false if you want to turn off logging to the browser's
* console.
* @default true
* @memberof MediaPlayer.utils.Debug#
*/
setLogToBrowserConsole: function(value) {
logToBrowserConsole = value;
},
/**
* Use this method to get the state of logToBrowserConsole.
* @returns {boolean} The current value of logToBrowserConsole
* @memberof MediaPlayer.utils.Debug#
*/
getLogToBrowserConsole: function() {
return logToBrowserConsole;
},
/**
* This method will allow you send log messages to either the browser's console and/or
* dispatch an event to capture at the media player level.
* @param arguments The message you want to log. The Arguments object is supported for
* this method so you can send in comma separated logging items.
* @memberof MediaPlayer.utils.Debug#
*/
log: function () {
var message = '',
logTime = null;
if (showLogTimestamp) {
logTime = new Date().getTime();
message += '[' + (logTime - startTime) + ']';
}
if (showCalleeName && this.getName) {
message += '[' + this.getName() + ']';
}
if (this.getMediaType && this.getMediaType()) {
message += '[' + this.getMediaType() + ']';
}
if (message.length > 0) {
message += ' ';
}
Array.apply(null, arguments).forEach(function(item) {
message += item + ' ';
});
if (logToBrowserConsole) {
videojs.log.debug(message);
}
eventBus.dispatchEvent({
type: 'log',
message: message
});
}
};
};
}
};
/*
* Add a css-class that is used to temporarily hide the error dialog while so that

@@ -236,0 +125,0 @@ * we don't see a flash of the dialog box when we remove the video element's src

{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": true,
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"unused": true,
"boss": true,
"eqnull": true,
"browser": true,
"node": true,
"predef": [
"QUnit",
"module",
"test",
"asyncTest",
"expect",
"start",
"stop",
"ok",
"equal",
"notEqual",
"deepEqual",
"notDeepEqual",
"strictEqual",
"notStrictEqual",
"throws",
"sinon",
"process",
"describe",
"beforeEach",
"it",
"browser",
"Dash",
"MediaPlayer"
],
"nonew": true,
"quotmark": "single",
"trailing": true,
"maxlen": 100
}
(function(window, videojs, qunit) {
'use strict';
var
// local QUnit aliases
// http://api.qunitjs.com/
// test(name, callback)
test = qunit.test,
// ok(value, [message])
ok = qunit.ok,
// strictEqual(actual, expected, [message])
strictEqual = qunit.strictEqual,
// deepEqual(actual, expected, [message])
deepEqual = qunit.deepEqual,
sampleSrc = {
src: 'movie.mpd',
type: 'application/dash+xml',
keySystemOptions: [
{
name: 'com.widevine.alpha',
options: {
extra: 'data',
licenseUrl: 'https://example.com/license'
}
}
]
},
sampleSrcNoDRM = {
src: 'movie.mpd',
type: 'application/dash+xml'
},
testHandleSource = function (source, fakeManifest, expectedKeySystemOptions) {
var
startupCalled = false,
attachViewCalled = false,
resetSrcCalled = false,
el = document.createElement('div'),
player = {
id: function(){ return 'id'; },
el: function(){ return el; },
options_: {},
options: function(){ return this.options_; },
bufferedPercent: function() { return 0; },
controls: function(){ return false; },
usingNativeControls: function(){ return false; },
on: function(){ return this; },
off: function() { return this; },
ready: function(){},
addChild: function(){},
trigger: function(){}
},
tech,
contextObj = { fake: 'context' },
//stubs
origContext = Dash.di.DashContext,
origMediaPlayer = MediaPlayer,
origVJSXHR = videojs.xhr,
origResetSrc = videojs.Html5DashJS.prototype.resetSrc_;
expect(8);
el.innerHTML = '<div />';
tech = new videojs.Html5(player, {});
Dash.di.DashContext = function () {
return contextObj;
};
window.MediaPlayer = function (context) {
deepEqual(context, contextObj, 'context is passed into MediaPlayer correctly');
return {
startup: function () {
startupCalled = true;
},
retrieveManifest: function (manifestUrl, callback) {
strictEqual(manifestUrl, 'movie.mpd', 'manifest url is requested via retrieveManifest');
return callback(fakeManifest, null);
},
attachView: function () {
attachViewCalled = true;
},
setAutoPlay: function (autoplay) {
strictEqual(autoplay, false, 'autoplay is set to false by default');
},
attachSource: function (manifest, keySystem, keySystemOptions) {
deepEqual(keySystemOptions, expectedKeySystemOptions,
'src and manifest key system options are merged');
deepEqual(manifest, fakeManifest, 'manifest object is sent to attachSource');
strictEqual(startupCalled, true, 'MediaPlayer.startup was called');
strictEqual(attachViewCalled, true, 'MediaPlayer.attachView was called');
strictEqual(resetSrcCalled, true, 'Html5DashJS#resetSrc_ was called');
tech.dispose();
// Restore
Dash.di.DashContext = origContext;
window.MediaPlayer = origMediaPlayer;
videojs.xhr = origVJSXHR;
videojs.Html5DashJS.prototype.resetSrc_ = origResetSrc;
}
};
};
window.MediaPlayer.utils = {
Debug: origMediaPlayer.utils.Debug
};
// We have to override this because PhantomJS does not have Encrypted Media Extensions
videojs.Html5DashJS.prototype.resetSrc_ = function (fn) {
resetSrcCalled = true;
return fn();
};
var dashSourceHandler = videojs.Html5.selectSourceHandler(source);
dashSourceHandler.handleSource(source, tech);
};
qunit.module('videojs-dash dash.js SourceHandler', {
setup: function() {
},
teardown: function() {
}
});
test('validate the Dash.js SourceHandler in Html5', function() {
var dashSource = {
src:'some.mpd',
type:'application/dash+xml'
},
maybeDashSource = {
src:'some.mpd'
},
nonDashSource = {
src:'some.mp4',
type:'video/mp4'
};
var dashSourceHandler = videojs.Html5.selectSourceHandler(dashSource);
ok(dashSourceHandler, 'A DASH handler was found');
strictEqual(dashSourceHandler.canHandleSource(dashSource), 'probably',
'canHandleSource with proper mime-type returns "probably"');
strictEqual(dashSourceHandler.canHandleSource(maybeDashSource), 'maybe',
'canHandleSource with expected extension returns "maybe"');
strictEqual(dashSourceHandler.canHandleSource(nonDashSource), '',
'canHandleSource with anything else returns ""');
});
test('validate buildDashJSProtData function', function() {
var output = videojs.Html5DashJS.buildDashJSProtData(sampleSrc.keySystemOptions);
var empty = videojs.Html5DashJS.buildDashJSProtData(undefined);
strictEqual(output['com.widevine.alpha'].laURL, 'https://example.com/license',
'licenceUrl converted to laURL');
deepEqual(empty, {}, 'undefined keySystemOptions returns empty object');
});
test('validate handleSource function with src-provided key options', function() {
var
manifestWithProtection = {
Period: {
AdaptationSet: []
}
},
mergedKeySystemOptions = {
'com.widevine.alpha': {
extra: 'data',
laURL:'https://example.com/license'
}
};
testHandleSource(sampleSrc, manifestWithProtection, mergedKeySystemOptions);
});
test('validate handleSource function with invalid manifest', function() {
var
manifestWithProtection = {},
mergedKeySystemOptions = {};
testHandleSource(sampleSrcNoDRM, manifestWithProtection, mergedKeySystemOptions);
});
})(window, window.videojs, window.QUnit);
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Test Player</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="../../node_modules/video.js/dist/video-js/video-js.css">
<link rel="stylesheet" href="../../src/css/videojs-dash.css">
</head>
<body>
<video id="example-video" width=600 height=300 class="video-js vjs-default-skin" controls>
</video>
<script src="../../node_modules/video.js/dist/video-js/video.novtt.dev.js"></script>
<!-- Dash.js -->
<script src="../../node_modules/dashjs/dist/dash.all.js"></script>
<!-- videojs-contrib-dash -->
<script src="../../src/js/videojs-dash.js"></script>
<script>
var player = videojs('example-video');
player.ready(function(){
player.src({
src: "http://html5.cablelabs.com:8100/cenc/wv/dash.mpd",
type: "application/dash+xml",
keySystemOptions: [{
name: "com.widevine.alpha",
options: {
"licenseUrl": "https://html5.cablelabs.com:8025"
}
}]
});
});
</script>
</body>
</html>
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Test Player</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="../../node_modules/video.js/dist/video-js/video-js.css">
<link rel="stylesheet" href="../../src/css/videojs-dash.css">
</head>
<body>
<video id="example-video" width=600 height=300 class="video-js vjs-default-skin" controls>
</video>
<script src="../../node_modules/video.js/dist/video-js/video.novtt.dev.js"></script>
<!-- Dash.js -->
<script src="../../node_modules/dashjs/dist/dash.all.js"></script>
<!-- videojs-contrib-dash -->
<script src="../../src/js/videojs-dash.js"></script>
<script>
var player = videojs('example-video');
player.ready(function(){
player.src({
src: "http://wams.edgesuite.net/media/SintelTrailer_MP4_from_WAME/sintel_trailer-1080p.ism/manifest(format=mpd-time-csf)",
type: "application/dash+xml"
});
});
</script>
</body>
</html>
var url = require('url'),
Player = require('videojs-automation'),
players = [{
suiteName: browser.name + ': MPEG-DASH Player',
pageUrl: url.resolve(browser.baseUrl, 'test/functional/no-drm-player.html')
}];
if (/chrome/i.test(browser.browserName)) {
players.push({
suiteName: browser.name + ': MPEG-DASH Player w/ Widevine DRM',
pageUrl: url.resolve(browser.baseUrl, 'test/functional/drm-player.html')
});
}
players.map(function(p) {
return describe(p.suiteName, function() {
var player;
beforeEach(function() {
player = new Player(p.pageUrl);
});
if (!/explorer/i.test(browser.browserName)) {
it('should have no console errors', function() {
player.bigPlayButton().click();
player.consoleLog().then(function(logs) {
expect(logs.length).toBe(0);
});
});
}
it('should have no player errors', function() {
expect(player.error()).toBeNull();
});
it('should play', function() {
player.bigPlayButton().click();
expect(player.isPlaying()).toBe(true);
});
});
});
(function(window, videojs, qunit) {
'use strict';
var
// local QUnit aliases
// http://api.qunitjs.com/
// module(name, {[setup][ ,teardown]})
module = qunit.module,
// test(name, callback)
test = qunit.test,
// ok(value, [message])
ok = qunit.ok;
module('videojs-dash globals');
test('has expected globals', function() {
ok(videojs.Html5DashJS, 'videojs has "Html5Dash" property');
ok(window.MediaPlayer, 'global has "MediaPlayer" property');
ok(window.Dash, 'global has "Dash" property');
});
})(window, window.videojs, window.QUnit);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Video.js Dash Integration</title>
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
<script>
// Fake MediaSource for Phantom testing
window.MediaSource = window.MediaSource || {};
</script>
<!-- QUnit -->
<link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css" />
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
<!-- Video.js -->
<script src="../node_modules/video.js/dist/video-js/video.dev.js"></script>
<!-- Dash.js -->
<script src="../node_modules/dashjs/dist/dash.all.js"></script>
<!-- videojs-contrib-dash -->
<script src="../src/js/videojs-dash.js"></script>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<!-- Tests -->
<script>
test('the environment is sane', function() {
ok(true, 'everything is swell');
});
</script>
<script src="globals.test.js"></script>
<script src="dashjs.test.js"></script>
</body>
</html>

Sorry, the diff of this file is not supported yet