initial commit

This commit is contained in:
2026-03-22 03:21:45 +02:00
commit 897fea9f4e
15431 changed files with 2548840 additions and 0 deletions

156
node_modules/vis/lib/shared/Activator.js generated vendored Normal file
View File

@@ -0,0 +1,156 @@
var keycharm = require('keycharm');
var Emitter = require('emitter-component');
var Hammer = require('../module/hammer');
var util = require('../util');
/**
* Turn an element into an clickToUse element.
* When not active, the element has a transparent overlay. When the overlay is
* clicked, the mode is changed to active.
* When active, the element is displayed with a blue border around it, and
* the interactive contents of the element can be used. When clicked outside
* the element, the elements mode is changed to inactive.
* @param {Element} container
* @constructor Activator
*/
function Activator(container) {
this.active = false;
this.dom = {
container: container
};
this.dom.overlay = document.createElement('div');
this.dom.overlay.className = 'vis-overlay';
this.dom.container.appendChild(this.dom.overlay);
this.hammer = Hammer(this.dom.overlay);
this.hammer.on('tap', this._onTapOverlay.bind(this));
// block all touch events (except tap)
var me = this;
var events = [
'tap', 'doubletap', 'press',
'pinch',
'pan', 'panstart', 'panmove', 'panend'
];
events.forEach(function (event) {
me.hammer.on(event, function (event) {
event.stopPropagation();
});
});
// attach a click event to the window, in order to deactivate when clicking outside the timeline
if (document && document.body) {
this.onClick = function (event) {
if (!_hasParent(event.target, container)) {
me.deactivate();
}
};
document.body.addEventListener('click', this.onClick);
}
if (this.keycharm !== undefined) {
this.keycharm.destroy();
}
this.keycharm = keycharm();
// keycharm listener only bounded when active)
this.escListener = this.deactivate.bind(this);
}
// turn into an event emitter
Emitter(Activator.prototype);
// The currently active activator
Activator.current = null;
/**
* Destroy the activator. Cleans up all created DOM and event listeners
*/
Activator.prototype.destroy = function () {
this.deactivate();
// remove dom
this.dom.overlay.parentNode.removeChild(this.dom.overlay);
// remove global event listener
if (this.onClick) {
document.body.removeEventListener('click', this.onClick);
}
// cleanup hammer instances
this.hammer.destroy();
this.hammer = null;
// FIXME: cleaning up hammer instances doesn't work (Timeline not removed from memory)
};
/**
* Activate the element
* Overlay is hidden, element is decorated with a blue shadow border
*/
Activator.prototype.activate = function () {
// we allow only one active activator at a time
if (Activator.current) {
Activator.current.deactivate();
}
Activator.current = this;
this.active = true;
this.dom.overlay.style.display = 'none';
util.addClassName(this.dom.container, 'vis-active');
this.emit('change');
this.emit('activate');
// ugly hack: bind ESC after emitting the events, as the Network rebinds all
// keyboard events on a 'change' event
this.keycharm.bind('esc', this.escListener);
};
/**
* Deactivate the element
* Overlay is displayed on top of the element
*/
Activator.prototype.deactivate = function () {
this.active = false;
this.dom.overlay.style.display = '';
util.removeClassName(this.dom.container, 'vis-active');
this.keycharm.unbind('esc', this.escListener);
this.emit('change');
this.emit('deactivate');
};
/**
* Handle a tap event: activate the container
* @param {Event} event The event
* @private
*/
Activator.prototype._onTapOverlay = function (event) {
// activate the container
this.activate();
event.stopPropagation();
};
/**
* Test whether the element has the requested parent element somewhere in
* its chain of parent nodes.
* @param {HTMLElement} element
* @param {HTMLElement} parent
* @returns {boolean} Returns true when the parent is found somewhere in the
* chain of parent nodes.
* @private
*/
function _hasParent(element, parent) {
while (element) {
if (element === parent) {
return true
}
element = element.parentNode;
}
return false;
}
module.exports = Activator;

570
node_modules/vis/lib/shared/ColorPicker.js generated vendored Normal file
View File

@@ -0,0 +1,570 @@
let Hammer = require('../module/hammer');
let hammerUtil = require('../hammerUtil');
let util = require('../util');
/**
* @param {number} [pixelRatio=1]
*/
class ColorPicker {
/**
* @param {number} [pixelRatio=1]
*/
constructor(pixelRatio = 1) {
this.pixelRatio = pixelRatio;
this.generated = false;
this.centerCoordinates = {x:289/2, y:289/2};
this.r = 289 * 0.49;
this.color = {r:255,g:255,b:255,a:1.0};
this.hueCircle = undefined;
this.initialColor = {r:255,g:255,b:255,a:1.0};
this.previousColor= undefined;
this.applied = false;
// bound by
this.updateCallback = () => {};
this.closeCallback = () => {};
// create all DOM elements
this._create();
}
/**
* this inserts the colorPicker into a div from the DOM
* @param {Element} container
*/
insertTo(container) {
if (this.hammer !== undefined) {
this.hammer.destroy();
this.hammer = undefined;
}
this.container = container;
this.container.appendChild(this.frame);
this._bindHammer();
this._setSize();
}
/**
* the callback is executed on apply and save. Bind it to the application
* @param {function} callback
*/
setUpdateCallback(callback) {
if (typeof callback === 'function') {
this.updateCallback = callback;
}
else {
throw new Error("Function attempted to set as colorPicker update callback is not a function.");
}
}
/**
* the callback is executed on apply and save. Bind it to the application
* @param {function} callback
*/
setCloseCallback(callback) {
if (typeof callback === 'function') {
this.closeCallback = callback;
}
else {
throw new Error("Function attempted to set as colorPicker closing callback is not a function.");
}
}
/**
*
* @param {string} color
* @returns {String}
* @private
*/
_isColorString(color) {
var htmlColors = {black: '#000000',navy: '#000080',darkblue: '#00008B',mediumblue: '#0000CD',blue: '#0000FF',darkgreen: '#006400',green: '#008000',teal: '#008080',darkcyan: '#008B8B',deepskyblue: '#00BFFF',darkturquoise: '#00CED1',mediumspringgreen: '#00FA9A',lime: '#00FF00',springgreen: '#00FF7F',aqua: '#00FFFF',cyan: '#00FFFF',midnightblue: '#191970',dodgerblue: '#1E90FF',lightseagreen: '#20B2AA',forestgreen: '#228B22',seagreen: '#2E8B57',darkslategray: '#2F4F4F',limegreen: '#32CD32',mediumseagreen: '#3CB371',turquoise: '#40E0D0',royalblue: '#4169E1',steelblue: '#4682B4',darkslateblue: '#483D8B',mediumturquoise: '#48D1CC',indigo: '#4B0082',darkolivegreen: '#556B2F',cadetblue: '#5F9EA0',cornflowerblue: '#6495ED',mediumaquamarine: '#66CDAA',dimgray: '#696969',slateblue: '#6A5ACD',olivedrab: '#6B8E23',slategray: '#708090',lightslategray: '#778899',mediumslateblue: '#7B68EE',lawngreen: '#7CFC00',chartreuse: '#7FFF00',aquamarine: '#7FFFD4',maroon: '#800000',purple: '#800080',olive: '#808000',gray: '#808080',skyblue: '#87CEEB',lightskyblue: '#87CEFA',blueviolet: '#8A2BE2',darkred: '#8B0000',darkmagenta: '#8B008B',saddlebrown: '#8B4513',darkseagreen: '#8FBC8F',lightgreen: '#90EE90',mediumpurple: '#9370D8',darkviolet: '#9400D3',palegreen: '#98FB98',darkorchid: '#9932CC',yellowgreen: '#9ACD32',sienna: '#A0522D',brown: '#A52A2A',darkgray: '#A9A9A9',lightblue: '#ADD8E6',greenyellow: '#ADFF2F',paleturquoise: '#AFEEEE',lightsteelblue: '#B0C4DE',powderblue: '#B0E0E6',firebrick: '#B22222',darkgoldenrod: '#B8860B',mediumorchid: '#BA55D3',rosybrown: '#BC8F8F',darkkhaki: '#BDB76B',silver: '#C0C0C0',mediumvioletred: '#C71585',indianred: '#CD5C5C',peru: '#CD853F',chocolate: '#D2691E',tan: '#D2B48C',lightgrey: '#D3D3D3',palevioletred: '#D87093',thistle: '#D8BFD8',orchid: '#DA70D6',goldenrod: '#DAA520',crimson: '#DC143C',gainsboro: '#DCDCDC',plum: '#DDA0DD',burlywood: '#DEB887',lightcyan: '#E0FFFF',lavender: '#E6E6FA',darksalmon: '#E9967A',violet: '#EE82EE',palegoldenrod: '#EEE8AA',lightcoral: '#F08080',khaki: '#F0E68C',aliceblue: '#F0F8FF',honeydew: '#F0FFF0',azure: '#F0FFFF',sandybrown: '#F4A460',wheat: '#F5DEB3',beige: '#F5F5DC',whitesmoke: '#F5F5F5',mintcream: '#F5FFFA',ghostwhite: '#F8F8FF',salmon: '#FA8072',antiquewhite: '#FAEBD7',linen: '#FAF0E6',lightgoldenrodyellow: '#FAFAD2',oldlace: '#FDF5E6',red: '#FF0000',fuchsia: '#FF00FF',magenta: '#FF00FF',deeppink: '#FF1493',orangered: '#FF4500',tomato: '#FF6347',hotpink: '#FF69B4',coral: '#FF7F50',darkorange: '#FF8C00',lightsalmon: '#FFA07A',orange: '#FFA500',lightpink: '#FFB6C1',pink: '#FFC0CB',gold: '#FFD700',peachpuff: '#FFDAB9',navajowhite: '#FFDEAD',moccasin: '#FFE4B5',bisque: '#FFE4C4',mistyrose: '#FFE4E1',blanchedalmond: '#FFEBCD',papayawhip: '#FFEFD5',lavenderblush: '#FFF0F5',seashell: '#FFF5EE',cornsilk: '#FFF8DC',lemonchiffon: '#FFFACD',floralwhite: '#FFFAF0',snow: '#FFFAFA',yellow: '#FFFF00',lightyellow: '#FFFFE0',ivory: '#FFFFF0',white: '#FFFFFF'};
if (typeof color === 'string') {
return htmlColors[color];
}
}
/**
* Set the color of the colorPicker
* Supported formats:
* 'red' --> HTML color string
* '#ffffff' --> hex string
* 'rbg(255,255,255)' --> rgb string
* 'rgba(255,255,255,1.0)' --> rgba string
* {r:255,g:255,b:255} --> rgb object
* {r:255,g:255,b:255,a:1.0} --> rgba object
* @param {string|Object} color
* @param {boolean} [setInitial=true]
*/
setColor(color, setInitial = true) {
if (color === 'none') {
return;
}
let rgba;
// if a html color shorthand is used, convert to hex
var htmlColor = this._isColorString(color);
if (htmlColor !== undefined) {
color = htmlColor;
}
// check format
if (util.isString(color) === true) {
if (util.isValidRGB(color) === true) {
let rgbaArray = color.substr(4).substr(0, color.length - 5).split(',');
rgba = {r:rgbaArray[0], g:rgbaArray[1], b:rgbaArray[2], a:1.0};
}
else if (util.isValidRGBA(color) === true) {
let rgbaArray = color.substr(5).substr(0, color.length - 6).split(',');
rgba = {r:rgbaArray[0], g:rgbaArray[1], b:rgbaArray[2], a:rgbaArray[3]};
}
else if (util.isValidHex(color) === true) {
let rgbObj = util.hexToRGB(color);
rgba = {r:rgbObj.r, g:rgbObj.g, b:rgbObj.b, a:1.0};
}
}
else {
if (color instanceof Object) {
if (color.r !== undefined && color.g !== undefined && color.b !== undefined) {
let alpha = color.a !== undefined ? color.a : '1.0';
rgba = {r:color.r, g:color.g, b:color.b, a:alpha};
}
}
}
// set color
if (rgba === undefined) {
throw new Error("Unknown color passed to the colorPicker. Supported are strings: rgb, hex, rgba. Object: rgb ({r:r,g:g,b:b,[a:a]}). Supplied: " + JSON.stringify(color));
}
else {
this._setColor(rgba, setInitial);
}
}
/**
* this shows the color picker.
* The hue circle is constructed once and stored.
*/
show() {
if (this.closeCallback !== undefined) {
this.closeCallback();
this.closeCallback = undefined;
}
this.applied = false;
this.frame.style.display = 'block';
this._generateHueCircle();
}
// ------------------------------------------ PRIVATE ----------------------------- //
/**
* Hide the picker. Is called by the cancel button.
* Optional boolean to store the previous color for easy access later on.
* @param {boolean} [storePrevious=true]
* @private
*/
_hide(storePrevious = true) {
// store the previous color for next time;
if (storePrevious === true) {
this.previousColor = util.extend({}, this.color);
}
if (this.applied === true) {
this.updateCallback(this.initialColor);
}
this.frame.style.display = 'none';
// call the closing callback, restoring the onclick method.
// this is in a setTimeout because it will trigger the show again before the click is done.
setTimeout(() => {
if (this.closeCallback !== undefined) {
this.closeCallback();
this.closeCallback = undefined;
}
},0);
}
/**
* bound to the save button. Saves and hides.
* @private
*/
_save() {
this.updateCallback(this.color);
this.applied = false;
this._hide();
}
/**
* Bound to apply button. Saves but does not close. Is undone by the cancel button.
* @private
*/
_apply() {
this.applied = true;
this.updateCallback(this.color);
this._updatePicker(this.color);
}
/**
* load the color from the previous session.
* @private
*/
_loadLast() {
if (this.previousColor !== undefined) {
this.setColor(this.previousColor, false);
}
else {
alert("There is no last color to load...");
}
}
/**
* set the color, place the picker
* @param {Object} rgba
* @param {boolean} [setInitial=true]
* @private
*/
_setColor(rgba, setInitial = true) {
// store the initial color
if (setInitial === true) {
this.initialColor = util.extend({}, rgba);
}
this.color = rgba;
let hsv = util.RGBToHSV(rgba.r, rgba.g, rgba.b);
let angleConvert = 2 * Math.PI;
let radius = this.r * hsv.s;
let x = this.centerCoordinates.x + radius * Math.sin(angleConvert * hsv.h);
let y = this.centerCoordinates.y + radius * Math.cos(angleConvert * hsv.h);
this.colorPickerSelector.style.left = x - 0.5 * this.colorPickerSelector.clientWidth + 'px';
this.colorPickerSelector.style.top = y - 0.5 * this.colorPickerSelector.clientHeight + 'px';
this._updatePicker(rgba);
}
/**
* bound to opacity control
* @param {number} value
* @private
*/
_setOpacity(value) {
this.color.a = value / 100;
this._updatePicker(this.color);
}
/**
* bound to brightness control
* @param {number} value
* @private
*/
_setBrightness(value) {
let hsv = util.RGBToHSV(this.color.r, this.color.g, this.color.b);
hsv.v = value / 100;
let rgba = util.HSVToRGB(hsv.h, hsv.s, hsv.v);
rgba['a'] = this.color.a;
this.color = rgba;
this._updatePicker();
}
/**
* update the color picker. A black circle overlays the hue circle to mimic the brightness decreasing.
* @param {Object} rgba
* @private
*/
_updatePicker(rgba = this.color) {
let hsv = util.RGBToHSV(rgba.r, rgba.g, rgba.b);
let ctx = this.colorPickerCanvas.getContext('2d');
if (this.pixelRation === undefined) {
this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1);
}
ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
// clear the canvas
let w = this.colorPickerCanvas.clientWidth;
let h = this.colorPickerCanvas.clientHeight;
ctx.clearRect(0, 0, w, h);
ctx.putImageData(this.hueCircle, 0,0);
ctx.fillStyle = 'rgba(0,0,0,' + (1- hsv.v) + ')';
ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
ctx.fill();
this.brightnessRange.value = 100 * hsv.v;
this.opacityRange.value = 100 * rgba.a;
this.initialColorDiv.style.backgroundColor = 'rgba(' + this.initialColor.r + ',' + this.initialColor.g + ',' + this.initialColor.b + ',' + this.initialColor.a + ')';
this.newColorDiv.style.backgroundColor = 'rgba(' + this.color.r + ',' + this.color.g + ',' + this.color.b + ',' + this.color.a + ')';
}
/**
* used by create to set the size of the canvas.
* @private
*/
_setSize() {
this.colorPickerCanvas.style.width = '100%';
this.colorPickerCanvas.style.height = '100%';
this.colorPickerCanvas.width = 289 * this.pixelRatio;
this.colorPickerCanvas.height = 289 * this.pixelRatio;
}
/**
* create all dom elements
* TODO: cleanup, lots of similar dom elements
* @private
*/
_create() {
this.frame = document.createElement('div');
this.frame.className = 'vis-color-picker';
this.colorPickerDiv = document.createElement('div');
this.colorPickerSelector = document.createElement('div');
this.colorPickerSelector.className = 'vis-selector';
this.colorPickerDiv.appendChild(this.colorPickerSelector);
this.colorPickerCanvas = document.createElement('canvas');
this.colorPickerDiv.appendChild(this.colorPickerCanvas);
if (!this.colorPickerCanvas.getContext) {
let noCanvas = document.createElement( 'DIV' );
noCanvas.style.color = 'red';
noCanvas.style.fontWeight = 'bold' ;
noCanvas.style.padding = '10px';
noCanvas.innerHTML = 'Error: your browser does not support HTML canvas';
this.colorPickerCanvas.appendChild(noCanvas);
}
else {
let ctx = this.colorPickerCanvas.getContext("2d");
this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1);
this.colorPickerCanvas.getContext("2d").setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
}
this.colorPickerDiv.className = 'vis-color';
this.opacityDiv = document.createElement('div');
this.opacityDiv.className = 'vis-opacity';
this.brightnessDiv = document.createElement('div');
this.brightnessDiv.className = 'vis-brightness';
this.arrowDiv = document.createElement('div');
this.arrowDiv.className = 'vis-arrow';
this.opacityRange = document.createElement('input');
try {
this.opacityRange.type = 'range'; // Not supported on IE9
this.opacityRange.min = '0';
this.opacityRange.max = '100';
}
// TODO: Add some error handling and remove this lint exception
catch (err) {} // eslint-disable-line no-empty
this.opacityRange.value = '100';
this.opacityRange.className = 'vis-range';
this.brightnessRange = document.createElement('input');
try {
this.brightnessRange.type = 'range'; // Not supported on IE9
this.brightnessRange.min = '0';
this.brightnessRange.max = '100';
}
// TODO: Add some error handling and remove this lint exception
catch (err) {} // eslint-disable-line no-empty
this.brightnessRange.value = '100';
this.brightnessRange.className = 'vis-range';
this.opacityDiv.appendChild(this.opacityRange);
this.brightnessDiv.appendChild(this.brightnessRange);
var me = this;
this.opacityRange.onchange = function () {me._setOpacity(this.value);};
this.opacityRange.oninput = function () {me._setOpacity(this.value);};
this.brightnessRange.onchange = function () {me._setBrightness(this.value);};
this.brightnessRange.oninput = function () {me._setBrightness(this.value);};
this.brightnessLabel = document.createElement("div");
this.brightnessLabel.className = "vis-label vis-brightness";
this.brightnessLabel.innerHTML = 'brightness:';
this.opacityLabel = document.createElement("div");
this.opacityLabel.className = "vis-label vis-opacity";
this.opacityLabel.innerHTML = 'opacity:';
this.newColorDiv = document.createElement("div");
this.newColorDiv.className = "vis-new-color";
this.newColorDiv.innerHTML = 'new';
this.initialColorDiv = document.createElement("div");
this.initialColorDiv.className = "vis-initial-color";
this.initialColorDiv.innerHTML = 'initial';
this.cancelButton = document.createElement("div");
this.cancelButton.className = "vis-button vis-cancel";
this.cancelButton.innerHTML = 'cancel';
this.cancelButton.onclick = this._hide.bind(this, false);
this.applyButton = document.createElement("div");
this.applyButton.className = "vis-button vis-apply";
this.applyButton.innerHTML = 'apply';
this.applyButton.onclick = this._apply.bind(this);
this.saveButton = document.createElement("div");
this.saveButton.className = "vis-button vis-save";
this.saveButton.innerHTML = 'save';
this.saveButton.onclick = this._save.bind(this);
this.loadButton = document.createElement("div");
this.loadButton.className = "vis-button vis-load";
this.loadButton.innerHTML = 'load last';
this.loadButton.onclick = this._loadLast.bind(this);
this.frame.appendChild(this.colorPickerDiv);
this.frame.appendChild(this.arrowDiv);
this.frame.appendChild(this.brightnessLabel);
this.frame.appendChild(this.brightnessDiv);
this.frame.appendChild(this.opacityLabel);
this.frame.appendChild(this.opacityDiv);
this.frame.appendChild(this.newColorDiv);
this.frame.appendChild(this.initialColorDiv);
this.frame.appendChild(this.cancelButton);
this.frame.appendChild(this.applyButton);
this.frame.appendChild(this.saveButton);
this.frame.appendChild(this.loadButton);
}
/**
* bind hammer to the color picker
* @private
*/
_bindHammer() {
this.drag = {};
this.pinch = {};
this.hammer = new Hammer(this.colorPickerCanvas);
this.hammer.get('pinch').set({enable: true});
hammerUtil.onTouch(this.hammer, (event) => {this._moveSelector(event)});
this.hammer.on('tap', (event) => {this._moveSelector(event)});
this.hammer.on('panstart', (event) => {this._moveSelector(event)});
this.hammer.on('panmove', (event) => {this._moveSelector(event)});
this.hammer.on('panend', (event) => {this._moveSelector(event)});
}
/**
* generate the hue circle. This is relatively heavy (200ms) and is done only once on the first time it is shown.
* @private
*/
_generateHueCircle() {
if (this.generated === false) {
let ctx = this.colorPickerCanvas.getContext('2d');
if (this.pixelRation === undefined) {
this.pixelRatio = (window.devicePixelRatio || 1) / (ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1);
}
ctx.setTransform(this.pixelRatio, 0, 0, this.pixelRatio, 0, 0);
// clear the canvas
let w = this.colorPickerCanvas.clientWidth;
let h = this.colorPickerCanvas.clientHeight;
ctx.clearRect(0, 0, w, h);
// draw hue circle
let x, y, hue, sat;
this.centerCoordinates = {x: w * 0.5, y: h * 0.5};
this.r = 0.49 * w;
let angleConvert = (2 * Math.PI) / 360;
let hfac = 1 / 360;
let sfac = 1 / this.r;
let rgb;
for (hue = 0; hue < 360; hue++) {
for (sat = 0; sat < this.r; sat++) {
x = this.centerCoordinates.x + sat * Math.sin(angleConvert * hue);
y = this.centerCoordinates.y + sat * Math.cos(angleConvert * hue);
rgb = util.HSVToRGB(hue * hfac, sat * sfac, 1);
ctx.fillStyle = 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
ctx.fillRect(x - 0.5, y - 0.5, 2, 2);
}
}
ctx.strokeStyle = 'rgba(0,0,0,1)';
ctx.circle(this.centerCoordinates.x, this.centerCoordinates.y, this.r);
ctx.stroke();
this.hueCircle = ctx.getImageData(0,0,w,h);
}
this.generated = true;
}
/**
* move the selector. This is called by hammer functions.
*
* @param {Event} event The event
* @private
*/
_moveSelector(event) {
let rect = this.colorPickerDiv.getBoundingClientRect();
let left = event.center.x - rect.left;
let top = event.center.y - rect.top;
let centerY = 0.5 * this.colorPickerDiv.clientHeight;
let centerX = 0.5 * this.colorPickerDiv.clientWidth;
let x = left - centerX;
let y = top - centerY;
let angle = Math.atan2(x,y);
let radius = 0.98 * Math.min(Math.sqrt(x * x + y * y), centerX);
let newTop = Math.cos(angle) * radius + centerY;
let newLeft = Math.sin(angle) * radius + centerX;
this.colorPickerSelector.style.top = newTop - 0.5 * this.colorPickerSelector.clientHeight + 'px';
this.colorPickerSelector.style.left = newLeft - 0.5 * this.colorPickerSelector.clientWidth + 'px';
// set color
let h = angle / (2 * Math.PI);
h = h < 0 ? h + 1 : h;
let s = radius / this.r;
let hsv = util.RGBToHSV(this.color.r, this.color.g, this.color.b);
hsv.h = h;
hsv.s = s;
let rgba = util.HSVToRGB(hsv.h, hsv.s, hsv.v);
rgba['a'] = this.color.a;
this.color = rgba;
// update previews
this.initialColorDiv.style.backgroundColor = 'rgba(' + this.initialColor.r + ',' + this.initialColor.g + ',' + this.initialColor.b + ',' + this.initialColor.a + ')';
this.newColorDiv.style.backgroundColor = 'rgba(' + this.color.r + ',' + this.color.g + ',' + this.color.b + ',' + this.color.a + ')';
}
}
export default ColorPicker;

737
node_modules/vis/lib/shared/Configurator.js generated vendored Normal file
View File

@@ -0,0 +1,737 @@
var util = require('../util');
var ColorPicker = require('./ColorPicker').default;
/**
* The way this works is for all properties of this.possible options, you can supply the property name in any form to list the options.
* Boolean options are recognised as Boolean
* Number options should be written as array: [default value, min value, max value, stepsize]
* Colors should be written as array: ['color', '#ffffff']
* Strings with should be written as array: [option1, option2, option3, ..]
*
* The options are matched with their counterparts in each of the modules and the values used in the configuration are
*/
class Configurator {
/**
* @param {Object} parentModule | the location where parentModule.setOptions() can be called
* @param {Object} defaultContainer | the default container of the module
* @param {Object} configureOptions | the fully configured and predefined options set found in allOptions.js
* @param {number} pixelRatio | canvas pixel ratio
*/
constructor(parentModule, defaultContainer, configureOptions, pixelRatio = 1) {
this.parent = parentModule;
this.changedOptions = [];
this.container = defaultContainer;
this.allowCreation = false;
this.options = {};
this.initialized = false;
this.popupCounter = 0;
this.defaultOptions = {
enabled: false,
filter: true,
container: undefined,
showButton: true
};
util.extend(this.options, this.defaultOptions);
this.configureOptions = configureOptions;
this.moduleOptions = {};
this.domElements = [];
this.popupDiv = {};
this.popupLimit = 5;
this.popupHistory = {};
this.colorPicker = new ColorPicker(pixelRatio);
this.wrapper = undefined;
}
/**
* refresh all options.
* Because all modules parse their options by themselves, we just use their options. We copy them here.
*
* @param {Object} options
*/
setOptions(options) {
if (options !== undefined) {
// reset the popup history because the indices may have been changed.
this.popupHistory = {};
this._removePopup();
let enabled = true;
if (typeof options === 'string') {
this.options.filter = options;
}
else if (options instanceof Array) {
this.options.filter = options.join();
}
else if (typeof options === 'object') {
if (options.container !== undefined) {
this.options.container = options.container;
}
if (options.filter !== undefined) {
this.options.filter = options.filter;
}
if (options.showButton !== undefined) {
this.options.showButton = options.showButton;
}
if (options.enabled !== undefined) {
enabled = options.enabled;
}
}
else if (typeof options === 'boolean') {
this.options.filter = true;
enabled = options;
}
else if (typeof options === 'function') {
this.options.filter = options;
enabled = true;
}
if (this.options.filter === false) {
enabled = false;
}
this.options.enabled = enabled;
}
this._clean();
}
/**
*
* @param {Object} moduleOptions
*/
setModuleOptions(moduleOptions) {
this.moduleOptions = moduleOptions;
if (this.options.enabled === true) {
this._clean();
if (this.options.container !== undefined) {
this.container = this.options.container;
}
this._create();
}
}
/**
* Create all DOM elements
* @private
*/
_create() {
this._clean();
this.changedOptions = [];
let filter = this.options.filter;
let counter = 0;
let show = false;
for (let option in this.configureOptions) {
if (this.configureOptions.hasOwnProperty(option)) {
this.allowCreation = false;
show = false;
if (typeof filter === 'function') {
show = filter(option,[]);
show = show || this._handleObject(this.configureOptions[option], [option], true);
}
else if (filter === true || filter.indexOf(option) !== -1) {
show = true;
}
if (show !== false) {
this.allowCreation = true;
// linebreak between categories
if (counter > 0) {
this._makeItem([]);
}
// a header for the category
this._makeHeader(option);
// get the sub options
this._handleObject(this.configureOptions[option], [option]);
}
counter++;
}
}
if (this.options.showButton === true) {
let generateButton = document.createElement('div');
generateButton.className = 'vis-configuration vis-config-button';
generateButton.innerHTML = 'generate options';
generateButton.onclick = () => {this._printOptions();};
generateButton.onmouseover = () => {generateButton.className = 'vis-configuration vis-config-button hover';};
generateButton.onmouseout = () => {generateButton.className = 'vis-configuration vis-config-button';};
this.optionsContainer = document.createElement('div');
this.optionsContainer.className = 'vis-configuration vis-config-option-container';
this.domElements.push(this.optionsContainer);
this.domElements.push(generateButton);
}
this._push();
//~ this.colorPicker.insertTo(this.container);
}
/**
* draw all DOM elements on the screen
* @private
*/
_push() {
this.wrapper = document.createElement('div');
this.wrapper.className = 'vis-configuration-wrapper';
this.container.appendChild(this.wrapper);
for (var i = 0; i < this.domElements.length; i++) {
this.wrapper.appendChild(this.domElements[i]);
}
this._showPopupIfNeeded()
}
/**
* delete all DOM elements
* @private
*/
_clean() {
for (var i = 0; i < this.domElements.length; i++) {
this.wrapper.removeChild(this.domElements[i]);
}
if (this.wrapper !== undefined) {
this.container.removeChild(this.wrapper);
this.wrapper = undefined;
}
this.domElements = [];
this._removePopup();
}
/**
* get the value from the actualOptions if it exists
* @param {array} path | where to look for the actual option
* @returns {*}
* @private
*/
_getValue(path) {
let base = this.moduleOptions;
for (let i = 0; i < path.length; i++) {
if (base[path[i]] !== undefined) {
base = base[path[i]];
}
else {
base = undefined;
break;
}
}
return base;
}
/**
* all option elements are wrapped in an item
* @param {Array} path | where to look for the actual option
* @param {Array.<Element>} domElements
* @returns {number}
* @private
*/
_makeItem(path, ...domElements) {
if (this.allowCreation === true) {
let item = document.createElement('div');
item.className = 'vis-configuration vis-config-item vis-config-s' + path.length;
domElements.forEach((element) => {
item.appendChild(element);
});
this.domElements.push(item);
return this.domElements.length;
}
return 0;
}
/**
* header for major subjects
* @param {string} name
* @private
*/
_makeHeader(name) {
let div = document.createElement('div');
div.className = 'vis-configuration vis-config-header';
div.innerHTML = name;
this._makeItem([],div);
}
/**
* make a label, if it is an object label, it gets different styling.
* @param {string} name
* @param {array} path | where to look for the actual option
* @param {string} objectLabel
* @returns {HTMLElement}
* @private
*/
_makeLabel(name, path, objectLabel = false) {
let div = document.createElement('div');
div.className = 'vis-configuration vis-config-label vis-config-s' + path.length;
if (objectLabel === true) {
div.innerHTML = '<i><b>' + name + ':</b></i>';
}
else {
div.innerHTML = name + ':';
}
return div;
}
/**
* make a dropdown list for multiple possible string optoins
* @param {Array.<number>} arr
* @param {number} value
* @param {array} path | where to look for the actual option
* @private
*/
_makeDropdown(arr, value, path) {
let select = document.createElement('select');
select.className = 'vis-configuration vis-config-select';
let selectedValue = 0;
if (value !== undefined) {
if (arr.indexOf(value) !== -1) {
selectedValue = arr.indexOf(value);
}
}
for (let i = 0; i < arr.length; i++) {
let option = document.createElement('option');
option.value = arr[i];
if (i === selectedValue) {
option.selected = 'selected';
}
option.innerHTML = arr[i];
select.appendChild(option);
}
let me = this;
select.onchange = function () {me._update(this.value, path);};
let label = this._makeLabel(path[path.length-1], path);
this._makeItem(path, label, select);
}
/**
* make a range object for numeric options
* @param {Array.<number>} arr
* @param {number} value
* @param {array} path | where to look for the actual option
* @private
*/
_makeRange(arr, value, path) {
let defaultValue = arr[0];
let min = arr[1];
let max = arr[2];
let step = arr[3];
let range = document.createElement('input');
range.className = 'vis-configuration vis-config-range';
try {
range.type = 'range'; // not supported on IE9
range.min = min;
range.max = max;
}
// TODO: Add some error handling and remove this lint exception
catch (err) {} // eslint-disable-line no-empty
range.step = step;
// set up the popup settings in case they are needed.
let popupString = '';
let popupValue = 0;
if (value !== undefined) {
let factor = 1.20;
if (value < 0 && value * factor < min) {
range.min = Math.ceil(value * factor);
popupValue = range.min;
popupString = 'range increased';
}
else if (value / factor < min) {
range.min = Math.ceil(value / factor);
popupValue = range.min;
popupString = 'range increased';
}
if (value * factor > max && max !== 1) {
range.max = Math.ceil(value * factor);
popupValue = range.max;
popupString = 'range increased';
}
range.value = value;
}
else {
range.value = defaultValue;
}
let input = document.createElement('input');
input.className = 'vis-configuration vis-config-rangeinput';
input.value = range.value;
var me = this;
range.onchange = function () {input.value = this.value; me._update(Number(this.value), path);};
range.oninput = function () {input.value = this.value; };
let label = this._makeLabel(path[path.length-1], path);
let itemIndex = this._makeItem(path, label, range, input);
// if a popup is needed AND it has not been shown for this value, show it.
if (popupString !== '' && this.popupHistory[itemIndex] !== popupValue) {
this.popupHistory[itemIndex] = popupValue;
this._setupPopup(popupString, itemIndex);
}
}
/**
* prepare the popup
* @param {string} string
* @param {number} index
* @private
*/
_setupPopup(string, index) {
if (this.initialized === true && this.allowCreation === true && this.popupCounter < this.popupLimit) {
let div = document.createElement("div");
div.id = "vis-configuration-popup";
div.className = "vis-configuration-popup";
div.innerHTML = string;
div.onclick = () => {this._removePopup()};
this.popupCounter += 1;
this.popupDiv = {html:div, index:index};
}
}
/**
* remove the popup from the dom
* @private
*/
_removePopup() {
if (this.popupDiv.html !== undefined) {
this.popupDiv.html.parentNode.removeChild(this.popupDiv.html);
clearTimeout(this.popupDiv.hideTimeout);
clearTimeout(this.popupDiv.deleteTimeout);
this.popupDiv = {};
}
}
/**
* Show the popup if it is needed.
* @private
*/
_showPopupIfNeeded() {
if (this.popupDiv.html !== undefined) {
let correspondingElement = this.domElements[this.popupDiv.index];
let rect = correspondingElement.getBoundingClientRect();
this.popupDiv.html.style.left = rect.left + "px";
this.popupDiv.html.style.top = rect.top - 30 + "px"; // 30 is the height;
document.body.appendChild(this.popupDiv.html)
this.popupDiv.hideTimeout = setTimeout(() => {
this.popupDiv.html.style.opacity = 0;
},1500);
this.popupDiv.deleteTimeout = setTimeout(() => {
this._removePopup();
},1800)
}
}
/**
* make a checkbox for boolean options.
* @param {number} defaultValue
* @param {number} value
* @param {array} path | where to look for the actual option
* @private
*/
_makeCheckbox(defaultValue, value, path) {
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.className = 'vis-configuration vis-config-checkbox';
checkbox.checked = defaultValue;
if (value !== undefined) {
checkbox.checked = value;
if (value !== defaultValue) {
if (typeof defaultValue === 'object') {
if (value !== defaultValue.enabled) {
this.changedOptions.push({path:path, value:value});
}
}
else {
this.changedOptions.push({path:path, value:value});
}
}
}
let me = this;
checkbox.onchange = function() {me._update(this.checked, path)};
let label = this._makeLabel(path[path.length-1], path);
this._makeItem(path, label, checkbox);
}
/**
* make a text input field for string options.
* @param {number} defaultValue
* @param {number} value
* @param {array} path | where to look for the actual option
* @private
*/
_makeTextInput(defaultValue, value, path) {
var checkbox = document.createElement('input');
checkbox.type = 'text';
checkbox.className = 'vis-configuration vis-config-text';
checkbox.value = value;
if (value !== defaultValue) {
this.changedOptions.push({path:path, value:value});
}
let me = this;
checkbox.onchange = function() {me._update(this.value, path)};
let label = this._makeLabel(path[path.length-1], path);
this._makeItem(path, label, checkbox);
}
/**
* make a color field with a color picker for color fields
* @param {Array.<number>} arr
* @param {number} value
* @param {array} path | where to look for the actual option
* @private
*/
_makeColorField(arr, value, path) {
let defaultColor = arr[1];
let div = document.createElement('div');
value = value === undefined ? defaultColor : value;
if (value !== 'none') {
div.className = 'vis-configuration vis-config-colorBlock';
div.style.backgroundColor = value;
}
else {
div.className = 'vis-configuration vis-config-colorBlock none';
}
value = value === undefined ? defaultColor : value;
div.onclick = () => {
this._showColorPicker(value,div,path);
};
let label = this._makeLabel(path[path.length-1], path);
this._makeItem(path,label, div);
}
/**
* used by the color buttons to call the color picker.
* @param {number} value
* @param {HTMLElement} div
* @param {array} path | where to look for the actual option
* @private
*/
_showColorPicker(value, div, path) {
// clear the callback from this div
div.onclick = function() {};
this.colorPicker.insertTo(div);
this.colorPicker.show();
this.colorPicker.setColor(value);
this.colorPicker.setUpdateCallback((color) => {
let colorString = 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',' + color.a + ')';
div.style.backgroundColor = colorString;
this._update(colorString,path);
});
// on close of the colorpicker, restore the callback.
this.colorPicker.setCloseCallback(() => {
div.onclick = () => {
this._showColorPicker(value,div,path);
};
});
}
/**
* parse an object and draw the correct items
* @param {Object} obj
* @param {array} [path=[]] | where to look for the actual option
* @param {boolean} [checkOnly=false]
* @returns {boolean}
* @private
*/
_handleObject(obj, path = [], checkOnly = false) {
let show = false;
let filter = this.options.filter;
let visibleInSet = false;
for (let subObj in obj) {
if (obj.hasOwnProperty(subObj)) {
show = true;
let item = obj[subObj];
let newPath = util.copyAndExtendArray(path, subObj);
if (typeof filter === 'function') {
show = filter(subObj,path);
// if needed we must go deeper into the object.
if (show === false) {
if (!(item instanceof Array) && typeof item !== 'string' && typeof item !== 'boolean' && item instanceof Object) {
this.allowCreation = false;
show = this._handleObject(item, newPath, true);
this.allowCreation = checkOnly === false;
}
}
}
if (show !== false) {
visibleInSet = true;
let value = this._getValue(newPath);
if (item instanceof Array) {
this._handleArray(item, value, newPath);
}
else if (typeof item === 'string') {
this._makeTextInput(item, value, newPath);
}
else if (typeof item === 'boolean') {
this._makeCheckbox(item, value, newPath);
}
else if (item instanceof Object) {
// collapse the physics options that are not enabled
let draw = true;
if (path.indexOf('physics') !== -1) {
if (this.moduleOptions.physics.solver !== subObj) {
draw = false;
}
}
if (draw === true) {
// initially collapse options with an disabled enabled option.
if (item.enabled !== undefined) {
let enabledPath = util.copyAndExtendArray(newPath, 'enabled');
let enabledValue = this._getValue(enabledPath);
if (enabledValue === true) {
let label = this._makeLabel(subObj, newPath, true);
this._makeItem(newPath, label);
visibleInSet = this._handleObject(item, newPath) || visibleInSet;
}
else {
this._makeCheckbox(item, enabledValue, newPath);
}
}
else {
let label = this._makeLabel(subObj, newPath, true);
this._makeItem(newPath, label);
visibleInSet = this._handleObject(item, newPath) || visibleInSet;
}
}
}
else {
console.error('dont know how to handle', item, subObj, newPath);
}
}
}
}
return visibleInSet;
}
/**
* handle the array type of option
* @param {Array.<number>} arr
* @param {number} value
* @param {array} path | where to look for the actual option
* @private
*/
_handleArray(arr, value, path) {
if (typeof arr[0] === 'string' && arr[0] === 'color') {
this._makeColorField(arr, value, path);
if (arr[1] !== value) {this.changedOptions.push({path:path, value:value});}
}
else if (typeof arr[0] === 'string') {
this._makeDropdown(arr, value, path);
if (arr[0] !== value) {this.changedOptions.push({path:path, value:value});}
}
else if (typeof arr[0] === 'number') {
this._makeRange(arr, value, path);
if (arr[0] !== value) {this.changedOptions.push({path:path, value:Number(value)});}
}
}
/**
* called to update the network with the new settings.
* @param {number} value
* @param {array} path | where to look for the actual option
* @private
*/
_update(value, path) {
let options = this._constructOptions(value,path);
if (this.parent.body && this.parent.body.emitter && this.parent.body.emitter.emit) {
this.parent.body.emitter.emit("configChange", options);
}
this.initialized = true;
this.parent.setOptions(options);
}
/**
*
* @param {string|Boolean} value
* @param {Array.<string>} path
* @param {{}} optionsObj
* @returns {{}}
* @private
*/
_constructOptions(value, path, optionsObj = {}) {
let pointer = optionsObj;
// when dropdown boxes can be string or boolean, we typecast it into correct types
value = value === 'true' ? true : value;
value = value === 'false' ? false : value;
for (let i = 0; i < path.length; i++) {
if (path[i] !== 'global') {
if (pointer[path[i]] === undefined) {
pointer[path[i]] = {};
}
if (i !== path.length - 1) {
pointer = pointer[path[i]];
}
else {
pointer[path[i]] = value;
}
}
}
return optionsObj;
}
/**
* @private
*/
_printOptions() {
let options = this.getOptions();
this.optionsContainer.innerHTML = '<pre>var options = ' + JSON.stringify(options, null, 2) + '</pre>';
}
/**
*
* @returns {{}} options
*/
getOptions() {
let options = {};
for (var i = 0; i < this.changedOptions.length; i++) {
this._constructOptions(this.changedOptions[i].value, this.changedOptions[i].path, options)
}
return options;
}
}
export default Configurator;

132
node_modules/vis/lib/shared/Popup.js generated vendored Normal file
View File

@@ -0,0 +1,132 @@
/**
* Popup is a class to create a popup window with some text
*/
class Popup {
/**
* @param {Element} container The container object.
* @param {string} overflowMethod How the popup should act to overflowing ('flip' or 'cap')
*/
constructor(container, overflowMethod) {
this.container = container;
this.overflowMethod = overflowMethod || 'cap';
this.x = 0;
this.y = 0;
this.padding = 5;
this.hidden = false;
// create the frame
this.frame = document.createElement('div');
this.frame.className = 'vis-tooltip';
this.container.appendChild(this.frame);
}
/**
* @param {number} x Horizontal position of the popup window
* @param {number} y Vertical position of the popup window
*/
setPosition(x, y) {
this.x = parseInt(x);
this.y = parseInt(y);
}
/**
* Set the content for the popup window. This can be HTML code or text.
* @param {string | Element} content
*/
setText(content) {
if (content instanceof Element) {
this.frame.innerHTML = '';
this.frame.appendChild(content);
}
else {
this.frame.innerHTML = content; // string containing text or HTML
}
}
/**
* Show the popup window
* @param {boolean} [doShow] Show or hide the window
*/
show(doShow) {
if (doShow === undefined) {
doShow = true;
}
if (doShow === true) {
var height = this.frame.clientHeight;
var width = this.frame.clientWidth;
var maxHeight = this.frame.parentNode.clientHeight;
var maxWidth = this.frame.parentNode.clientWidth;
var left = 0, top = 0;
if (this.overflowMethod == 'flip') {
var isLeft = false, isTop = true; // Where around the position it's located
if (this.y - height < this.padding) {
isTop = false;
}
if (this.x + width > maxWidth - this.padding) {
isLeft = true;
}
if (isLeft) {
left = this.x - width;
} else {
left = this.x;
}
if (isTop) {
top = this.y - height;
} else {
top = this.y;
}
} else {
top = (this.y - height);
if (top + height + this.padding > maxHeight) {
top = maxHeight - height - this.padding;
}
if (top < this.padding) {
top = this.padding;
}
left = this.x;
if (left + width + this.padding > maxWidth) {
left = maxWidth - width - this.padding;
}
if (left < this.padding) {
left = this.padding;
}
}
this.frame.style.left = left + "px";
this.frame.style.top = top + "px";
this.frame.style.visibility = "visible";
this.hidden = false;
}
else {
this.hide();
}
}
/**
* Hide the popup window
*/
hide() {
this.hidden = true;
this.frame.style.left = "0";
this.frame.style.top = "0";
this.frame.style.visibility = "hidden";
}
/**
* Remove the popup window
*/
destroy() {
this.frame.parentNode.removeChild(this.frame); // Remove element from DOM
}
}
export default Popup;

355
node_modules/vis/lib/shared/Validator.js generated vendored Normal file
View File

@@ -0,0 +1,355 @@
var util = require('../util');
let errorFound = false;
let allOptions;
let printStyle = 'background: #FFeeee; color: #dd0000';
/**
* Used to validate options.
*/
class Validator {
/**
* @ignore
*/
constructor() {
}
/**
* Main function to be called
* @param {Object} options
* @param {Object} referenceOptions
* @param {Object} subObject
* @returns {boolean}
* @static
*/
static validate(options, referenceOptions, subObject) {
errorFound = false;
allOptions = referenceOptions;
let usedOptions = referenceOptions;
if (subObject !== undefined) {
usedOptions = referenceOptions[subObject];
}
Validator.parse(options, usedOptions, []);
return errorFound;
}
/**
* Will traverse an object recursively and check every value
* @param {Object} options
* @param {Object} referenceOptions
* @param {array} path | where to look for the actual option
* @static
*/
static parse(options, referenceOptions, path) {
for (let option in options) {
if (options.hasOwnProperty(option)) {
Validator.check(option, options, referenceOptions, path);
}
}
}
/**
* Check every value. If the value is an object, call the parse function on that object.
* @param {string} option
* @param {Object} options
* @param {Object} referenceOptions
* @param {array} path | where to look for the actual option
* @static
*/
static check(option, options, referenceOptions, path) {
if (referenceOptions[option] === undefined && referenceOptions.__any__ === undefined) {
Validator.getSuggestion(option, referenceOptions, path);
return;
}
let referenceOption = option;
let is_object = true;
if (referenceOptions[option] === undefined && referenceOptions.__any__ !== undefined) {
// NOTE: This only triggers if the __any__ is in the top level of the options object.
// THAT'S A REALLY BAD PLACE TO ALLOW IT!!!!
// TODO: Examine if needed, remove if possible
// __any__ is a wildcard. Any value is accepted and will be further analysed by reference.
referenceOption = '__any__';
// if the any-subgroup is not a predefined object in the configurator,
// we do not look deeper into the object.
is_object = (Validator.getType(options[option]) === 'object');
}
else {
// Since all options in the reference are objects, we can check whether
// they are supposed to be the object to look for the __type__ field.
// if this is an object, we check if the correct type has been supplied to account for shorthand options.
}
let refOptionObj = referenceOptions[referenceOption];
if (is_object && refOptionObj.__type__ !== undefined) {
refOptionObj = refOptionObj.__type__;
}
Validator.checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path);
}
/**
*
* @param {string} option | the option property
* @param {Object} options | The supplied options object
* @param {Object} referenceOptions | The reference options containing all options and their allowed formats
* @param {string} referenceOption | Usually this is the same as option, except when handling an __any__ tag.
* @param {string} refOptionObj | This is the type object from the reference options
* @param {Array} path | where in the object is the option
* @static
*/
static checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path) {
let log = function(message) {
console.log('%c' + message + Validator.printLocation(path, option), printStyle);
};
let optionType = Validator.getType(options[option]);
let refOptionType = refOptionObj[optionType];
if (refOptionType !== undefined) {
// if the type is correct, we check if it is supposed to be one of a few select values
if (Validator.getType(refOptionType) === 'array' && refOptionType.indexOf(options[option]) === -1) {
log('Invalid option detected in "' + option + '".' +
' Allowed values are:' + Validator.print(refOptionType) +
' not "' + options[option] + '". ');
errorFound = true;
}
else if (optionType === 'object' && referenceOption !== "__any__") {
path = util.copyAndExtendArray(path, option);
Validator.parse(options[option], referenceOptions[referenceOption], path);
}
}
else if (refOptionObj['any'] === undefined) {
// type of the field is incorrect and the field cannot be any
log('Invalid type received for "' + option +
'". Expected: ' + Validator.print(Object.keys(refOptionObj)) +
'. Received [' + optionType + '] "' + options[option] + '"');
errorFound = true;
}
}
/**
*
* @param {Object|boolean|number|string|Array.<number>|Date|Node|Moment|undefined|null} object
* @returns {string}
* @static
*/
static getType(object) {
var type = typeof object;
if (type === 'object') {
if (object === null) {
return 'null';
}
if (object instanceof Boolean) {
return 'boolean';
}
if (object instanceof Number) {
return 'number';
}
if (object instanceof String) {
return 'string';
}
if (Array.isArray(object)) {
return 'array';
}
if (object instanceof Date) {
return 'date';
}
if (object.nodeType !== undefined) {
return 'dom';
}
if (object._isAMomentObject === true) {
return 'moment';
}
return 'object';
}
else if (type === 'number') {
return 'number';
}
else if (type === 'boolean') {
return 'boolean';
}
else if (type === 'string') {
return 'string';
}
else if (type === undefined) {
return 'undefined';
}
return type;
}
/**
* @param {string} option
* @param {Object} options
* @param {Array.<string>} path
* @static
*/
static getSuggestion(option, options, path) {
let localSearch = Validator.findInOptions(option,options,path,false);
let globalSearch = Validator.findInOptions(option,allOptions,[],true);
let localSearchThreshold = 8;
let globalSearchThreshold = 4;
let msg;
if (localSearch.indexMatch !== undefined) {
msg = ' in ' + Validator.printLocation(localSearch.path, option,'') +
'Perhaps it was incomplete? Did you mean: "' + localSearch.indexMatch + '"?\n\n';
}
else if (globalSearch.distance <= globalSearchThreshold && localSearch.distance > globalSearch.distance) {
msg = ' in ' + Validator.printLocation(localSearch.path, option,'') +
'Perhaps it was misplaced? Matching option found at: ' +
Validator.printLocation(globalSearch.path, globalSearch.closestMatch,'');
}
else if (localSearch.distance <= localSearchThreshold) {
msg = '. Did you mean "' + localSearch.closestMatch + '"?' +
Validator.printLocation(localSearch.path, option);
}
else {
msg = '. Did you mean one of these: ' + Validator.print(Object.keys(options)) +
Validator.printLocation(path, option);
}
console.log('%cUnknown option detected: "' + option + '"' + msg, printStyle);
errorFound = true;
}
/**
* traverse the options in search for a match.
* @param {string} option
* @param {Object} options
* @param {Array} path | where to look for the actual option
* @param {boolean} [recursive=false]
* @returns {{closestMatch: string, path: Array, distance: number}}
* @static
*/
static findInOptions(option, options, path, recursive = false) {
let min = 1e9;
let closestMatch = '';
let closestMatchPath = [];
let lowerCaseOption = option.toLowerCase();
let indexMatch = undefined;
for (let op in options) { // eslint-disable-line guard-for-in
let distance;
if (options[op].__type__ !== undefined && recursive === true) {
let result = Validator.findInOptions(option, options[op], util.copyAndExtendArray(path,op));
if (min > result.distance) {
closestMatch = result.closestMatch;
closestMatchPath = result.path;
min = result.distance;
indexMatch = result.indexMatch;
}
}
else {
if (op.toLowerCase().indexOf(lowerCaseOption) !== -1) {
indexMatch = op;
}
distance = Validator.levenshteinDistance(option, op);
if (min > distance) {
closestMatch = op;
closestMatchPath = util.copyArray(path);
min = distance;
}
}
}
return {closestMatch:closestMatch, path:closestMatchPath, distance:min, indexMatch: indexMatch};
}
/**
* @param {Array.<string>} path
* @param {Object} option
* @param {string} prefix
* @returns {String}
* @static
*/
static printLocation(path, option, prefix = 'Problem value found at: \n') {
let str = '\n\n' + prefix + 'options = {\n';
for (let i = 0; i < path.length; i++) {
for (let j = 0; j < i + 1; j++) {
str += ' ';
}
str += path[i] + ': {\n'
}
for (let j = 0; j < path.length + 1; j++) {
str += ' ';
}
str += option + '\n';
for (let i = 0; i < path.length + 1; i++) {
for (let j = 0; j < path.length - i; j++) {
str += ' ';
}
str += '}\n'
}
return str + '\n\n';
}
/**
* @param {Object} options
* @returns {String}
* @static
*/
static print(options) {
return JSON.stringify(options).replace(/(\")|(\[)|(\])|(,"__type__")/g, "").replace(/(\,)/g, ', ')
}
/**
* Compute the edit distance between the two given strings
* http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Levenshtein_distance#JavaScript
*
* Copyright (c) 2011 Andrei Mackenzie
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* @param {string} a
* @param {string} b
* @returns {Array.<Array.<number>>}}
* @static
*/
static levenshteinDistance(a, b) {
if (a.length === 0) return b.length;
if (b.length === 0) return a.length;
var matrix = [];
// increment along the first column of each row
var i;
for (i = 0; i <= b.length; i++) {
matrix[i] = [i];
}
// increment each column in the first row
var j;
for (j = 0; j <= a.length; j++) {
matrix[0][j] = j;
}
// Fill in the rest of the matrix
for (i = 1; i <= b.length; i++) {
for (j = 1; j <= a.length; j++) {
if (b.charAt(i - 1) == a.charAt(j - 1)) {
matrix[i][j] = matrix[i - 1][j - 1];
} else {
matrix[i][j] = Math.min(matrix[i - 1][j - 1] + 1, // substitution
Math.min(matrix[i][j - 1] + 1, // insertion
matrix[i - 1][j] + 1)); // deletion
}
}
}
return matrix[b.length][a.length];
}
}
export default Validator;
export {printStyle}

14
node_modules/vis/lib/shared/activator.css generated vendored Normal file
View File

@@ -0,0 +1,14 @@
.vis .overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
/* Must be displayed above for example selected Timeline items */
z-index: 10;
}
.vis-active {
box-shadow: 0 0 10px #86d5f8;
}

6
node_modules/vis/lib/shared/bootstrap.css generated vendored Normal file
View File

@@ -0,0 +1,6 @@
/* override some bootstrap styles screwing up the timelines css */
.vis [class*="span"] {
min-height: 0;
width: auto;
}

288
node_modules/vis/lib/shared/configuration.css generated vendored Normal file
View File

@@ -0,0 +1,288 @@
div.vis-configuration {
position:relative;
display:block;
float:left;
font-size:12px;
}
div.vis-configuration-wrapper {
display:block;
width:700px;
}
div.vis-configuration-wrapper::after {
clear: both;
content: "";
display: block;
}
div.vis-configuration.vis-config-option-container{
display:block;
width:495px;
background-color: #ffffff;
border:2px solid #f7f8fa;
border-radius:4px;
margin-top:20px;
left:10px;
padding-left:5px;
}
div.vis-configuration.vis-config-button{
display:block;
width:495px;
height:25px;
vertical-align: middle;
line-height:25px;
background-color: #f7f8fa;
border:2px solid #ceced0;
border-radius:4px;
margin-top:20px;
left:10px;
padding-left:5px;
cursor: pointer;
margin-bottom:30px;
}
div.vis-configuration.vis-config-button.hover{
background-color: #4588e6;
border:2px solid #214373;
color:#ffffff;
}
div.vis-configuration.vis-config-item{
display:block;
float:left;
width:495px;
height:25px;
vertical-align: middle;
line-height:25px;
}
div.vis-configuration.vis-config-item.vis-config-s2{
left:10px;
background-color: #f7f8fa;
padding-left:5px;
border-radius:3px;
}
div.vis-configuration.vis-config-item.vis-config-s3{
left:20px;
background-color: #e4e9f0;
padding-left:5px;
border-radius:3px;
}
div.vis-configuration.vis-config-item.vis-config-s4{
left:30px;
background-color: #cfd8e6;
padding-left:5px;
border-radius:3px;
}
div.vis-configuration.vis-config-header{
font-size:18px;
font-weight: bold;
}
div.vis-configuration.vis-config-label{
width:120px;
height:25px;
line-height: 25px;
}
div.vis-configuration.vis-config-label.vis-config-s3{
width:110px;
}
div.vis-configuration.vis-config-label.vis-config-s4{
width:100px;
}
div.vis-configuration.vis-config-colorBlock{
top:1px;
width:30px;
height:19px;
border:1px solid #444444;
border-radius:2px;
padding:0px;
margin:0px;
cursor:pointer;
}
input.vis-configuration.vis-config-checkbox {
left:-5px;
}
input.vis-configuration.vis-config-rangeinput{
position:relative;
top:-5px;
width:60px;
/*height:13px;*/
padding:1px;
margin:0;
pointer-events:none;
}
input.vis-configuration.vis-config-range{
/*removes default webkit styles*/
-webkit-appearance: none;
/*fix for FF unable to apply focus style bug */
border: 0px solid white;
background-color:rgba(0,0,0,0);
/*required for proper track sizing in FF*/
width: 300px;
height:20px;
}
input.vis-configuration.vis-config-range::-webkit-slider-runnable-track {
width: 300px;
height: 5px;
background: #dedede; /* Old browsers */
background: -moz-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#dedede), color-stop(99%,#c8c8c8)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #dedede 0%,#c8c8c8 99%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #dedede 0%,#c8c8c8 99%); /* IE10+ */
background: linear-gradient(to bottom, #dedede 0%,#c8c8c8 99%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dedede', endColorstr='#c8c8c8',GradientType=0 ); /* IE6-9 */
border: 1px solid #999999;
box-shadow: #aaaaaa 0px 0px 3px 0px;
border-radius: 3px;
}
input.vis-configuration.vis-config-range::-webkit-slider-thumb {
-webkit-appearance: none;
border: 1px solid #14334b;
height: 17px;
width: 17px;
border-radius: 50%;
background: #3876c2; /* Old browsers */
background: -moz-linear-gradient(top, #3876c2 0%, #385380 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3876c2), color-stop(100%,#385380)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #3876c2 0%,#385380 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #3876c2 0%,#385380 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #3876c2 0%,#385380 100%); /* IE10+ */
background: linear-gradient(to bottom, #3876c2 0%,#385380 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3876c2', endColorstr='#385380',GradientType=0 ); /* IE6-9 */
box-shadow: #111927 0px 0px 1px 0px;
margin-top: -7px;
}
input.vis-configuration.vis-config-range:focus {
outline: none;
}
input.vis-configuration.vis-config-range:focus::-webkit-slider-runnable-track {
background: #9d9d9d; /* Old browsers */
background: -moz-linear-gradient(top, #9d9d9d 0%, #c8c8c8 99%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9d9d9d), color-stop(99%,#c8c8c8)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #9d9d9d 0%,#c8c8c8 99%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #9d9d9d 0%,#c8c8c8 99%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #9d9d9d 0%,#c8c8c8 99%); /* IE10+ */
background: linear-gradient(to bottom, #9d9d9d 0%,#c8c8c8 99%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9d9d9d', endColorstr='#c8c8c8',GradientType=0 ); /* IE6-9 */
}
input.vis-configuration.vis-config-range::-moz-range-track {
width: 300px;
height: 10px;
background: #dedede; /* Old browsers */
background: -moz-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#dedede), color-stop(99%,#c8c8c8)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #dedede 0%,#c8c8c8 99%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #dedede 0%, #c8c8c8 99%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #dedede 0%,#c8c8c8 99%); /* IE10+ */
background: linear-gradient(to bottom, #dedede 0%,#c8c8c8 99%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#dedede', endColorstr='#c8c8c8',GradientType=0 ); /* IE6-9 */
border: 1px solid #999999;
box-shadow: #aaaaaa 0px 0px 3px 0px;
border-radius: 3px;
}
input.vis-configuration.vis-config-range::-moz-range-thumb {
border: none;
height: 16px;
width: 16px;
border-radius: 50%;
background: #385380;
}
/*hide the outline behind the border*/
input.vis-configuration.vis-config-range:-moz-focusring{
outline: 1px solid white;
outline-offset: -1px;
}
input.vis-configuration.vis-config-range::-ms-track {
width: 300px;
height: 5px;
/*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */
background: transparent;
/*leave room for the larger thumb to overflow with a transparent border */
border-color: transparent;
border-width: 6px 0;
/*remove default tick marks*/
color: transparent;
}
input.vis-configuration.vis-config-range::-ms-fill-lower {
background: #777;
border-radius: 10px;
}
input.vis-configuration.vis-config-range::-ms-fill-upper {
background: #ddd;
border-radius: 10px;
}
input.vis-configuration.vis-config-range::-ms-thumb {
border: none;
height: 16px;
width: 16px;
border-radius: 50%;
background: #385380;
}
input.vis-configuration.vis-config-range:focus::-ms-fill-lower {
background: #888;
}
input.vis-configuration.vis-config-range:focus::-ms-fill-upper {
background: #ccc;
}
.vis-configuration-popup {
position: absolute;
background: rgba(57, 76, 89, 0.85);
border: 2px solid #f2faff;
line-height:30px;
height:30px;
width:150px;
text-align:center;
color: #ffffff;
font-size:14px;
border-radius:4px;
-webkit-transition: opacity 0.3s ease-in-out;
-moz-transition: opacity 0.3s ease-in-out;
transition: opacity 0.3s ease-in-out;
}
.vis-configuration-popup:after, .vis-configuration-popup:before {
left: 100%;
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.vis-configuration-popup:after {
border-color: rgba(136, 183, 213, 0);
border-left-color: rgba(57, 76, 89, 0.85);
border-width: 8px;
margin-top: -8px;
}
.vis-configuration-popup:before {
border-color: rgba(194, 225, 245, 0);
border-left-color: #f2faff;
border-width: 12px;
margin-top: -12px;
}

21
node_modules/vis/lib/shared/tooltip.css generated vendored Normal file
View File

@@ -0,0 +1,21 @@
div.vis-tooltip {
position: absolute;
visibility: hidden;
padding: 5px;
white-space: nowrap;
font-family: verdana;
font-size:14px;
color:#000000;
background-color: #f5f4ed;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
border: 1px solid #808074;
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
pointer-events: none;
z-index: 5;
}