feat: Phase 1 — extract the client (web SPA + desktop) to dtoro/oikos-web
Problem: the hexagonal refactor churns the backend tree for nine more phases; the UI delivery stack (web/ SPA, cmd/desktop Wails wrapper, compose/web image) must move to its own repo first so doc/layout rewrites land once on a backend-only tree. Change: - New repo git.hubris.network/dtoro/oikos-web (v0.33.0): web/, desktop/ (updateURL repointed to oikos-web releases), compose/, own CI (web + desktop jobs), own deploy script (CI-green gate, TOCTOU guard, version-tagged images, prune-to-3), own webhook receiver on :9798 + launchd unit, own compose project publishing the same 8091:80. - Cutover executed on mac-mini in order: oikos stack's web service stopped+removed, oikos-web project brought up on 8091; outer Caddy untouched (targets the published port) — serving + Authentik flow + /wails 404 quirk verified post-cutover. - Stripped from oikos: web/, cmd/desktop/, compose/web/, desktop CI workflow, ci.yml web job, Makefile ui/desktop/desktop-package/install targets, the compose web service, oikos-web from deploy.sh's fallback prune list; wails + go-keyring dropped from go.mod, vendor synced. - README / CONTRIBUTING / AGENTS.md / .agents dev+operations docs now point at the new repo; mbse + mascot design docs carry a path note. Risk: production SPA serving depends on the new pipeline now; rollback is versioned-image re-up of the old web service from a pre-split checkout (port 8091). Desktop builds installed before the split still check dtoro/oikos releases — one manual reinstall, noted in the oikos-web release notes. Verification: go vet, make test (race), make generate-check, golangci (no new findings; baseline down 400→365); post-cutover curls — localhost:8091 200, /wails/runtime.js 404, outer Caddy 302 Authentik.
This commit is contained in:
390
web/node_modules/sigma/dist/normalization-02a974d4.cjs.dev.js
generated
vendored
Normal file
390
web/node_modules/sigma/dist/normalization-02a974d4.cjs.dev.js
generated
vendored
Normal file
@@ -0,0 +1,390 @@
|
||||
'use strict';
|
||||
|
||||
var isGraph = require('graphology-utils/is-graph');
|
||||
var colors = require('./colors-fe6de9d2.cjs.dev.js');
|
||||
|
||||
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
||||
|
||||
var isGraph__default = /*#__PURE__*/_interopDefault(isGraph);
|
||||
|
||||
var linear = function linear(k) {
|
||||
return k;
|
||||
};
|
||||
var quadraticIn = function quadraticIn(k) {
|
||||
return k * k;
|
||||
};
|
||||
var quadraticOut = function quadraticOut(k) {
|
||||
return k * (2 - k);
|
||||
};
|
||||
var quadraticInOut = function quadraticInOut(k) {
|
||||
if ((k *= 2) < 1) return 0.5 * k * k;
|
||||
return -0.5 * (--k * (k - 2) - 1);
|
||||
};
|
||||
var cubicIn = function cubicIn(k) {
|
||||
return k * k * k;
|
||||
};
|
||||
var cubicOut = function cubicOut(k) {
|
||||
return --k * k * k + 1;
|
||||
};
|
||||
var cubicInOut = function cubicInOut(k) {
|
||||
if ((k *= 2) < 1) return 0.5 * k * k * k;
|
||||
return 0.5 * ((k -= 2) * k * k + 2);
|
||||
};
|
||||
var easings = {
|
||||
linear: linear,
|
||||
quadraticIn: quadraticIn,
|
||||
quadraticOut: quadraticOut,
|
||||
quadraticInOut: quadraticInOut,
|
||||
cubicIn: cubicIn,
|
||||
cubicOut: cubicOut,
|
||||
cubicInOut: cubicInOut
|
||||
};
|
||||
|
||||
/**
|
||||
* Defaults.
|
||||
*/
|
||||
|
||||
var ANIMATE_DEFAULTS = {
|
||||
easing: "quadraticInOut",
|
||||
duration: 150
|
||||
};
|
||||
|
||||
/**
|
||||
* Function used to animate the nodes.
|
||||
*/
|
||||
function animateNodes(graph, targets, opts, callback) {
|
||||
var options = Object.assign({}, ANIMATE_DEFAULTS, opts);
|
||||
var easing = typeof options.easing === "function" ? options.easing : easings[options.easing];
|
||||
var start = Date.now();
|
||||
var startPositions = {};
|
||||
for (var node in targets) {
|
||||
var attrs = targets[node];
|
||||
startPositions[node] = {};
|
||||
for (var _k in attrs) startPositions[node][_k] = graph.getNodeAttribute(node, _k);
|
||||
}
|
||||
var frame = null;
|
||||
var _step = function step() {
|
||||
frame = null;
|
||||
var p = (Date.now() - start) / options.duration;
|
||||
if (p >= 1) {
|
||||
// Animation is done
|
||||
for (var _node in targets) {
|
||||
var _attrs = targets[_node];
|
||||
|
||||
// We use given values to avoid precision issues and for convenience
|
||||
for (var _k2 in _attrs) graph.setNodeAttribute(_node, _k2, _attrs[_k2]);
|
||||
}
|
||||
if (typeof callback === "function") callback();
|
||||
return;
|
||||
}
|
||||
p = easing(p);
|
||||
for (var _node2 in targets) {
|
||||
var _attrs2 = targets[_node2];
|
||||
var s = startPositions[_node2];
|
||||
for (var _k3 in _attrs2) graph.setNodeAttribute(_node2, _k3, _attrs2[_k3] * p + s[_k3] * (1 - p));
|
||||
}
|
||||
frame = requestAnimationFrame(_step);
|
||||
};
|
||||
_step();
|
||||
return function () {
|
||||
if (frame) cancelAnimationFrame(frame);
|
||||
};
|
||||
}
|
||||
|
||||
function identity() {
|
||||
return Float32Array.of(1, 0, 0, 0, 1, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
// TODO: optimize
|
||||
function scale(m, x, y) {
|
||||
m[0] = x;
|
||||
m[4] = typeof y === "number" ? y : x;
|
||||
return m;
|
||||
}
|
||||
function rotate(m, r) {
|
||||
var s = Math.sin(r),
|
||||
c = Math.cos(r);
|
||||
m[0] = c;
|
||||
m[1] = s;
|
||||
m[3] = -s;
|
||||
m[4] = c;
|
||||
return m;
|
||||
}
|
||||
function translate(m, x, y) {
|
||||
m[6] = x;
|
||||
m[7] = y;
|
||||
return m;
|
||||
}
|
||||
function multiply(a, b) {
|
||||
var a00 = a[0],
|
||||
a01 = a[1],
|
||||
a02 = a[2];
|
||||
var a10 = a[3],
|
||||
a11 = a[4],
|
||||
a12 = a[5];
|
||||
var a20 = a[6],
|
||||
a21 = a[7],
|
||||
a22 = a[8];
|
||||
var b00 = b[0],
|
||||
b01 = b[1],
|
||||
b02 = b[2];
|
||||
var b10 = b[3],
|
||||
b11 = b[4],
|
||||
b12 = b[5];
|
||||
var b20 = b[6],
|
||||
b21 = b[7],
|
||||
b22 = b[8];
|
||||
a[0] = b00 * a00 + b01 * a10 + b02 * a20;
|
||||
a[1] = b00 * a01 + b01 * a11 + b02 * a21;
|
||||
a[2] = b00 * a02 + b01 * a12 + b02 * a22;
|
||||
a[3] = b10 * a00 + b11 * a10 + b12 * a20;
|
||||
a[4] = b10 * a01 + b11 * a11 + b12 * a21;
|
||||
a[5] = b10 * a02 + b11 * a12 + b12 * a22;
|
||||
a[6] = b20 * a00 + b21 * a10 + b22 * a20;
|
||||
a[7] = b20 * a01 + b21 * a11 + b22 * a21;
|
||||
a[8] = b20 * a02 + b21 * a12 + b22 * a22;
|
||||
return a;
|
||||
}
|
||||
function multiplyVec2(a, b) {
|
||||
var z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
|
||||
var a00 = a[0];
|
||||
var a01 = a[1];
|
||||
var a10 = a[3];
|
||||
var a11 = a[4];
|
||||
var a20 = a[6];
|
||||
var a21 = a[7];
|
||||
var b0 = b.x;
|
||||
var b1 = b.y;
|
||||
return {
|
||||
x: b0 * a00 + b1 * a10 + a20 * z,
|
||||
y: b0 * a01 + b1 * a11 + a21 * z
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* In sigma, the graph is normalized into a [0, 1], [0, 1] square, before being given to the various renderers. This
|
||||
* helps to deal with quadtree in particular.
|
||||
* But at some point, we need to rescale it so that it takes the best place in the screen, i.e. we always want to see two
|
||||
* nodes "touching" opposite sides of the graph, with the camera being at its default state.
|
||||
*
|
||||
* This function determines this ratio.
|
||||
*/
|
||||
function getCorrectionRatio(viewportDimensions, graphDimensions) {
|
||||
var viewportRatio = viewportDimensions.height / viewportDimensions.width;
|
||||
var graphRatio = graphDimensions.height / graphDimensions.width;
|
||||
|
||||
// If the stage and the graphs are in different directions (such as the graph being wider that tall while the stage
|
||||
// is taller than wide), we can stop here to have indeed nodes touching opposite sides:
|
||||
if (viewportRatio < 1 && graphRatio > 1 || viewportRatio > 1 && graphRatio < 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Else, we need to fit the graph inside the stage:
|
||||
// 1. If the graph is "squarer" (i.e. with a ratio closer to 1), we need to make the largest sides touch;
|
||||
// 2. If the stage is "squarer", we need to make the smallest sides touch.
|
||||
return Math.min(Math.max(graphRatio, 1 / graphRatio), Math.max(1 / viewportRatio, viewportRatio));
|
||||
}
|
||||
|
||||
/**
|
||||
* Function returning a matrix from the current state of the camera.
|
||||
*/
|
||||
function matrixFromCamera(state, viewportDimensions, graphDimensions, padding, inverse) {
|
||||
// TODO: it's possible to optimize this drastically!
|
||||
var angle = state.angle,
|
||||
ratio = state.ratio,
|
||||
x = state.x,
|
||||
y = state.y;
|
||||
var width = viewportDimensions.width,
|
||||
height = viewportDimensions.height;
|
||||
var matrix = identity();
|
||||
var smallestDimension = Math.min(width, height) - 2 * padding;
|
||||
var correctionRatio = getCorrectionRatio(viewportDimensions, graphDimensions);
|
||||
if (!inverse) {
|
||||
multiply(matrix, scale(identity(), 2 * (smallestDimension / width) * correctionRatio, 2 * (smallestDimension / height) * correctionRatio));
|
||||
multiply(matrix, rotate(identity(), -angle));
|
||||
multiply(matrix, scale(identity(), 1 / ratio));
|
||||
multiply(matrix, translate(identity(), -x, -y));
|
||||
} else {
|
||||
multiply(matrix, translate(identity(), x, y));
|
||||
multiply(matrix, scale(identity(), ratio));
|
||||
multiply(matrix, rotate(identity(), angle));
|
||||
multiply(matrix, scale(identity(), width / smallestDimension / 2 / correctionRatio, height / smallestDimension / 2 / correctionRatio));
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* All these transformations we apply on the matrix to get it rescale the graph
|
||||
* as we want make it very hard to get pixel-perfect distances in WebGL. This
|
||||
* function returns a factor that properly cancels the matrix effect on lengths.
|
||||
*
|
||||
* [jacomyal]
|
||||
* To be fully honest, I can't really explain happens here... I notice that the
|
||||
* following ratio works (i.e. it correctly compensates the matrix impact on all
|
||||
* camera states I could try):
|
||||
* > `R = size(V) / size(M * V) / W`
|
||||
* as long as `M * V` is in the direction of W (ie. parallel to (Ox)). It works
|
||||
* as well with H and a vector that transforms into something parallel to (Oy).
|
||||
*
|
||||
* Also, note that we use `angle` and not `-angle` (that would seem logical,
|
||||
* since we want to anticipate the rotation), because the image is vertically
|
||||
* swapped in WebGL.
|
||||
*/
|
||||
function getMatrixImpact(matrix, cameraState, viewportDimensions) {
|
||||
var _multiplyVec = multiplyVec2(matrix, {
|
||||
x: Math.cos(cameraState.angle),
|
||||
y: Math.sin(cameraState.angle)
|
||||
}, 0),
|
||||
x = _multiplyVec.x,
|
||||
y = _multiplyVec.y;
|
||||
return 1 / Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) / viewportDimensions.width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function returning the graph's node extent in x & y.
|
||||
*/
|
||||
function graphExtent(graph) {
|
||||
if (!graph.order) return {
|
||||
x: [0, 1],
|
||||
y: [0, 1]
|
||||
};
|
||||
var xMin = Infinity;
|
||||
var xMax = -Infinity;
|
||||
var yMin = Infinity;
|
||||
var yMax = -Infinity;
|
||||
graph.forEachNode(function (_, attr) {
|
||||
var x = attr.x,
|
||||
y = attr.y;
|
||||
if (x < xMin) xMin = x;
|
||||
if (x > xMax) xMax = x;
|
||||
if (y < yMin) yMin = y;
|
||||
if (y > yMax) yMax = y;
|
||||
});
|
||||
return {
|
||||
x: [xMin, xMax],
|
||||
y: [yMin, yMax]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the graph variable is a valid graph, and if sigma can render it.
|
||||
*/
|
||||
function validateGraph(graph) {
|
||||
// check if it's a valid graphology instance
|
||||
if (!isGraph__default["default"](graph)) throw new Error("Sigma: invalid graph instance.");
|
||||
|
||||
// check if nodes have x/y attributes
|
||||
graph.forEachNode(function (key, attributes) {
|
||||
if (!Number.isFinite(attributes.x) || !Number.isFinite(attributes.y)) {
|
||||
throw new Error("Sigma: Coordinates of node ".concat(key, " are invalid. A node must have a numeric 'x' and 'y' attribute."));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used to create DOM elements easily.
|
||||
*/
|
||||
function createElement(tag, style, attributes) {
|
||||
var element = document.createElement(tag);
|
||||
if (style) {
|
||||
for (var k in style) {
|
||||
element.style[k] = style[k];
|
||||
}
|
||||
}
|
||||
if (attributes) {
|
||||
for (var _k in attributes) {
|
||||
element.setAttribute(_k, attributes[_k]);
|
||||
}
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function returning the browser's pixel ratio.
|
||||
*/
|
||||
function getPixelRatio() {
|
||||
if (typeof window.devicePixelRatio !== "undefined") return window.devicePixelRatio;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ordering the given elements in reverse z-order so they drawn
|
||||
* the correct way.
|
||||
*/
|
||||
function zIndexOrdering(_extent, getter, elements) {
|
||||
// If k is > n, we'll use a standard sort
|
||||
return elements.sort(function (a, b) {
|
||||
var zA = getter(a) || 0,
|
||||
zB = getter(b) || 0;
|
||||
if (zA < zB) return -1;
|
||||
if (zA > zB) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
// TODO: counting sort optimization
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory returning a function normalizing the given node's position & size.
|
||||
*/
|
||||
|
||||
function createNormalizationFunction(extent) {
|
||||
var _extent$x = colors._slicedToArray(extent.x, 2),
|
||||
minX = _extent$x[0],
|
||||
maxX = _extent$x[1],
|
||||
_extent$y = colors._slicedToArray(extent.y, 2),
|
||||
minY = _extent$y[0],
|
||||
maxY = _extent$y[1];
|
||||
var ratio = Math.max(maxX - minX, maxY - minY),
|
||||
dX = (maxX + minX) / 2,
|
||||
dY = (maxY + minY) / 2;
|
||||
if (ratio === 0 || Math.abs(ratio) === Infinity || isNaN(ratio)) ratio = 1;
|
||||
if (isNaN(dX)) dX = 0;
|
||||
if (isNaN(dY)) dY = 0;
|
||||
var fn = function fn(data) {
|
||||
return {
|
||||
x: 0.5 + (data.x - dX) / ratio,
|
||||
y: 0.5 + (data.y - dY) / ratio
|
||||
};
|
||||
};
|
||||
|
||||
// TODO: possibility to apply this in batch over array of indices
|
||||
fn.applyTo = function (data) {
|
||||
data.x = 0.5 + (data.x - dX) / ratio;
|
||||
data.y = 0.5 + (data.y - dY) / ratio;
|
||||
};
|
||||
fn.inverse = function (data) {
|
||||
return {
|
||||
x: dX + ratio * (data.x - 0.5),
|
||||
y: dY + ratio * (data.y - 0.5)
|
||||
};
|
||||
};
|
||||
fn.ratio = ratio;
|
||||
return fn;
|
||||
}
|
||||
|
||||
exports.ANIMATE_DEFAULTS = ANIMATE_DEFAULTS;
|
||||
exports.animateNodes = animateNodes;
|
||||
exports.createElement = createElement;
|
||||
exports.createNormalizationFunction = createNormalizationFunction;
|
||||
exports.cubicIn = cubicIn;
|
||||
exports.cubicInOut = cubicInOut;
|
||||
exports.cubicOut = cubicOut;
|
||||
exports.easings = easings;
|
||||
exports.getCorrectionRatio = getCorrectionRatio;
|
||||
exports.getMatrixImpact = getMatrixImpact;
|
||||
exports.getPixelRatio = getPixelRatio;
|
||||
exports.graphExtent = graphExtent;
|
||||
exports.identity = identity;
|
||||
exports.linear = linear;
|
||||
exports.matrixFromCamera = matrixFromCamera;
|
||||
exports.multiply = multiply;
|
||||
exports.multiplyVec2 = multiplyVec2;
|
||||
exports.quadraticIn = quadraticIn;
|
||||
exports.quadraticInOut = quadraticInOut;
|
||||
exports.quadraticOut = quadraticOut;
|
||||
exports.rotate = rotate;
|
||||
exports.scale = scale;
|
||||
exports.translate = translate;
|
||||
exports.validateGraph = validateGraph;
|
||||
exports.zIndexOrdering = zIndexOrdering;
|
||||
Reference in New Issue
Block a user