Add side panels, task selection, graph animation, and project docs

- Foldable left panel (user profile) and right panel (task details)
- Clicking a task in the list or graph node selects it and shows details
- Both views (task list + graph) always mounted via absolute inset-0 for
  correct canvas dimensions; tabs toggle visibility with opacity
- Graph node selection animation: other nodes repel outward (charge -600),
  then selected node smoothly slides to center (500ms cubic ease-out),
  then charge restores to -120 and graph stabilizes
- Graph re-fits on tab switch and panel resize via ResizeObserver
- Fix UUID string IDs throughout (backend returns UUIDs, not integers)
- Add TaskDetailPanel, UserPanel components
- Add CLAUDE.md project documentation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Alvis
2026-04-08 11:23:06 +00:00
parent 5c7edd4bbc
commit f1d51b8cc8
23998 changed files with 3242708 additions and 0 deletions

21
frontend/node_modules/kapsule/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Vasco Asturiano
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.

239
frontend/node_modules/kapsule/README.md generated vendored Normal file
View File

@@ -0,0 +1,239 @@
Kapsule
=======
[![NPM package][npm-img]][npm-url]
[![Build Size][build-size-img]][build-size-url]
[![NPM Downloads][npm-downloads-img]][npm-downloads-url]
A closure/class based Web Component library, loosely inspired by the [reusable charts pattern](https://bost.ocks.org/mike/chart/) commonly found in [D3](https://d3js.org/) components.
See also [react-kapsule](https://github.com/vasturiano/react-kapsule) for direct integration with React.
## Quick start
```js
import Kapsule from 'kapsule';
```
or using a *script* tag
```html
<script src="//cdn.jsdelivr.net/npm/kapsule"></script>
```
## Usage example
### Define the component
```js
const ColoredText = Kapsule({
props: {
color: { default: 'red' },
text: {}
},
init(domElement, state) {
state.elem = document.createElement('span');
domElement.appendChild(state.elem);
},
update(state) {
state.elem.style.color = state.color;
state.elem.textContent = state.text;
}
});
```
### Instantiate the component
```js
const myText = new ColoredText(<myDOMElement>);
```
### (Re-)Rendering
```js
myText
.color('blue')
.text('foo');
```
## API Reference
### Generation
<b>Kapsule</b>([<i>config</i>])
This returns a new class that encapsulates the web component. The returned class constructor expects a DOM element argument, onto which the component will be attached throughout its lifecycle. It also accepts an optional `options` object as second argument. The `options` object gets passed verbatim to the `init` object for interpretation. The instantiation triggers the internal `init` method as specified in the config.
The component's instance is an object of methods (defined by its config `props` and `methods`) that can be called for interacting with the component.
Example:
```js
const Comp = Kapsule(compConfig);
const myInstance = new Comp(<myDOMElement>, { /* options */ })
.prop1('someVal')
.prop2('anotherVal');
```
### Component configuration
The config object passed to Kapsule supports 5 properties: `props`, `methods`, `stateInit`, `init` and `update`.
All of these are optional and not required for the component to work, however calling `Kapsule({})` generates a dumb component that has no functionality nor interaction.
Extended example:
```js
const Comp = Kapsule({
props: {
propName: propConfig,
...
},
methods: {
methodName: function(state, ...args) { ... },
...
},
stateInit() {
return {
stateItem: initVal,
...
}
},
init(domNode, state, componentOptions) {
...
},
update(state) {
...
}
});
```
#### <b>props</b>: { propName: propConfig, ... }
Each registered prop inside `props` will declare its own getter/setter method in the component's instance state. This method will have the signature: `myInstance.propName(`[<i>propVal</i>]`)`.
If called without an argument, the method will function as a getter, returning the current value of the prop. If called with a value it will act as a setter, setting the value in the component's internal state, and returning the component's instance for convenience of method chaining. If the value passed in the setter is `undefined`, the default value will be applied.
The <b>propConfig</b> object supports 3 properties: `default`, `triggerUpdate` and `onChange`.
Extended prop example:
```js
{
props: {
propName: {
default: 6,
triggerUpdate: false,
onChange: function(newVal, state) { ... }
}
}
}
```
##### <b>default</b>
(default: `null`)
This defines the default value of the prop if it's not set by the instance consumer.
##### <b>triggerUpdate</b>
(default: `true`)
This defines whether changes to this prop should trigger the component's `update` method. Generally, if the `update` method does not take this prop into account, you can save some performance by setting this to `false`.
##### <b>onChange(newVal, state, prevVal)</b>
(default: `null`)
Here you can specify an event handler that gets triggered whenever this property is modified by the instance consumer. In some circumstances it's useful to keep update changes here instead of in the `update` method to isolate prop-specific functionality.
The previous value is also included for convenience.
The `this` context of this method is set to the component's instance.
#### <b>methods</b>: { methodName: function(state, ...args) { ... }, ... }
Each registered method inside `methods` will expose an additional method in the component's instance. These methods can be seen as a more generic version of the getter/setters in `props`, and allows the specification of more custom component interactions.
The exposed method will have the signature:
`myInstance.methodName(...args)`
The `this` context of each of this methods is set to the component's instance. If the method does not naturally return a value, it's advised to end the method with `return this;` so that it can be used in method chaining.
#### <b>stateInit(componentOptions)</b>
Use this method's return object to initialize the values of any internal state. This should only be used for state that is not exposed externally via `props`.
This state initialization gets ran as soon as the component is instantiated, and right before the `init` method is called.
Example:
```js
function stateInit() {
return {
stateItem: initVal,
...
}
}
```
#### <b>init(domNode, state, componentOptions)</b>
This method initializes the web component by attaching it to a DOM element. This method is only called once, during the component instantiation.
This is where DOM operations should be performed for the <b>static</b> parts of the document that do not change throughout its lifecycle.
Example:
```js
function init(domNode, state, { label: '' }) {
state.elem = document.createElement('div'); // static scaffolding div
domElement.appendChild(state.elem);
const labelElem = document.createElement('span');
labelElem.textContent = label; // static label from component options
state.elem.appendChild(labelElem);
}
```
The `this` context of this method is set to the component's instance.
Returning a value from this method has no effect.
#### <b>update(state, changedProps)</b>
This method is triggered once right after the `init` method finishes, and afterwards whenever a `prop` changes.
This method should contain the DOM operations for the <b>dynamic</b> parts of the document that change according to the component `props`.
Example:
```js
function update(state) {
state.elem.style.width = state.pxWidth + 'px';
}
```
Note that multiple calls to `update()` due to prop changes are internally debounced for performance optimization. This is so that the consumer can request multiple chained prop changes without each one triggering an update, but it instead being batched as one update.
The props that were updated since the last update cycle (or all if it's the first update) are included in the second argument `changedProps`. This is an object that lists all the updated props and their previous value. For example:
```js
{
pxWidth: 10, // previous value of pxWidth
color: 'blue'
}
```
When applying the initial default values, the previous prop value is referenced as `undefined`.
The `this` context of this method is set to the component's instance.
Returning a value from this method has no effect.
### Other methods
#### <b>resetProps</b>()
Each instance will get automatically exposed a convenience function `resetProps`, which when called will reset the internal state of all the `props` to their defined default values.
This will trigger an update call immediately after the props have been reset.
Example:
```js
myInstance
.propA('someVal')
.resetProps(); // propA gets reset to its default value
```
[npm-img]: https://img.shields.io/npm/v/kapsule
[npm-url]: https://npmjs.org/package/kapsule
[build-size-img]: https://img.shields.io/bundlephobia/minzip/kapsule
[build-size-url]: https://bundlephobia.com/result?p=kapsule
[npm-downloads-img]: https://img.shields.io/npm/dt/kapsule
[npm-downloads-url]: https://www.npmtrends.com/kapsule

45
frontend/node_modules/kapsule/dist/kapsule.d.ts generated vendored Normal file
View File

@@ -0,0 +1,45 @@
type InitOptions = object;
type PropVal = any;
type StateVal = any;
interface State {
_rerender: () => void;
[stateItem: string]: StateVal;
}
interface PropCfg {
default?: PropVal;
onChange?(newVal: PropVal, state: State, prevVal: PropVal): void;
triggerUpdate?: boolean;
}
type MethodCfg = (state: State, ...args: any[]) => any;
interface KapsuleCfg {
props?: { [prop: string]: PropCfg };
methods?: { [method: string]: MethodCfg };
aliases?: { [propOrMethod: string]: string };
stateInit?: (initOptions?: InitOptions) => Partial<State>;
init?: (
contructorItem?: any,
state?: State,
initOptions?: InitOptions
) => void;
update: (state?: State, changedProps?: { [prop: string]: PropVal }) => void;
}
type PropGetter = () => PropVal;
type PropSetter = (val: PropVal) => KapsuleClass;
type KapsuleMethod = (...args: any[]) => any;
declare class KapsuleClass {
constructor(element: HTMLElement, initOptions?: InitOptions);
resetProps(): KapsuleClass;
[propOrMethod: string]: PropGetter | PropSetter | KapsuleMethod;
}
declare function Kapsule(cfg?: KapsuleCfg): KapsuleClass;
export { KapsuleClass, Kapsule as default };
export type { KapsuleCfg };

683
frontend/node_modules/kapsule/dist/kapsule.js generated vendored Normal file
View File

@@ -0,0 +1,683 @@
// Version 1.16.3 kapsule - https://github.com/vasturiano/kapsule
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Kapsule = factory());
})(this, (function () { 'use strict';
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) return r;
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
}
function _createClass(e, r, t) {
return Object.defineProperty(e, "prototype", {
writable: false
}), e;
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = true,
o = false;
try {
if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = true, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
/**
* Gets the timestamp of the number of milliseconds that have elapsed since
* the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @since 2.4.0
* @category Date
* @returns {number} Returns the timestamp.
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => Logs the number of milliseconds it took for the deferred invocation.
*/
var now = function() {
return root.Date.now();
};
/** Used to match a single whitespace character. */
var reWhitespace = /\s/;
/**
* Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
* character of `string`.
*
* @private
* @param {string} string The string to inspect.
* @returns {number} Returns the index of the last non-whitespace character.
*/
function trimmedEndIndex(string) {
var index = string.length;
while (index-- && reWhitespace.test(string.charAt(index))) {}
return index;
}
/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;
/**
* The base implementation of `_.trim`.
*
* @private
* @param {string} string The string to trim.
* @returns {string} Returns the trimmed string.
*/
function baseTrim(string) {
return string
? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')
: string;
}
/** Built-in value references. */
var Symbol$1 = root.Symbol;
/** Used for built-in method references. */
var objectProto$1 = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto$1.hasOwnProperty;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString$1 = objectProto$1.toString;
/** Built-in value references. */
var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined;
/**
* A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the raw `toStringTag`.
*/
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag$1),
tag = value[symToStringTag$1];
try {
value[symToStringTag$1] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString$1.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag$1] = tag;
} else {
delete value[symToStringTag$1];
}
}
return result;
}
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
* of values.
*/
var nativeObjectToString = objectProto.toString;
/**
* Converts `value` to a string using `Object.prototype.toString`.
*
* @private
* @param {*} value The value to convert.
* @returns {string} Returns the converted string.
*/
function objectToString(value) {
return nativeObjectToString.call(value);
}
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;
/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;
/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;
/**
* Converts `value` to a number.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to process.
* @returns {number} Returns the number.
* @example
*
* _.toNumber(3.2);
* // => 3.2
*
* _.toNumber(Number.MIN_VALUE);
* // => 5e-324
*
* _.toNumber(Infinity);
* // => Infinity
*
* _.toNumber('3.2');
* // => 3.2
*/
function toNumber(value) {
if (typeof value == 'number') {
return value;
}
if (isSymbol(value)) {
return NAN;
}
if (isObject(value)) {
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
value = isObject(other) ? (other + '') : other;
}
if (typeof value != 'string') {
return value === 0 ? value : +value;
}
value = baseTrim(value);
var isBinary = reIsBinary.test(value);
return (isBinary || reIsOctal.test(value))
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
: (reIsBadHex.test(value) ? NAN : +value);
}
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* Provide `options` to indicate whether `func` should be invoked on the
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
* with the last arguments provided to the debounced function. Subsequent
* calls to the debounced function return the result of the last `func`
* invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // Avoid costly calculations while the window size is in flux.
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
* jQuery(element).on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
* jQuery(source).on('message', debounced);
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime,
lastInvokeTime = 0,
leading = false,
maxing = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
maxing = 'maxWait' in options;
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs,
thisArg = lastThis;
lastArgs = lastThis = undefined;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time;
// Start the timer for the trailing edge.
timerId = setTimeout(timerExpired, wait);
// Invoke the leading edge.
return leading ? invokeFunc(time) : result;
}
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
timeWaiting = wait - timeSinceLastCall;
return maxing
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting;
}
function shouldInvoke(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
}
function timerExpired() {
var time = now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = undefined;
return result;
}
function cancel() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge(now());
}
function debounced() {
var time = now(),
isInvoking = shouldInvoke(time);
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime);
}
if (maxing) {
// Handle invocations in a tight loop.
clearTimeout(timerId);
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
var Prop = /*#__PURE__*/_createClass(function Prop(name, _ref) {
var _ref$default = _ref["default"],
defaultVal = _ref$default === void 0 ? null : _ref$default,
_ref$triggerUpdate = _ref.triggerUpdate,
triggerUpdate = _ref$triggerUpdate === void 0 ? true : _ref$triggerUpdate,
_ref$onChange = _ref.onChange,
onChange = _ref$onChange === void 0 ? function (newVal, state) {} : _ref$onChange;
_classCallCheck(this, Prop);
this.name = name;
this.defaultVal = defaultVal;
this.triggerUpdate = triggerUpdate;
this.onChange = onChange;
});
function index (_ref2) {
var _ref2$stateInit = _ref2.stateInit,
stateInit = _ref2$stateInit === void 0 ? function () {
return {};
} : _ref2$stateInit,
_ref2$props = _ref2.props,
rawProps = _ref2$props === void 0 ? {} : _ref2$props,
_ref2$methods = _ref2.methods,
methods = _ref2$methods === void 0 ? {} : _ref2$methods,
_ref2$aliases = _ref2.aliases,
aliases = _ref2$aliases === void 0 ? {} : _ref2$aliases,
_ref2$init = _ref2.init,
initFn = _ref2$init === void 0 ? function () {} : _ref2$init,
_ref2$update = _ref2.update,
updateFn = _ref2$update === void 0 ? function () {} : _ref2$update;
// Parse props into Prop instances
var props = Object.keys(rawProps).map(function (propName) {
return new Prop(propName, rawProps[propName]);
});
return function KapsuleComp() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var classMode = !!(this instanceof KapsuleComp ? this.constructor : void 0);
var nodeElement = classMode ? args.shift() : undefined;
var _args$ = args[0],
options = _args$ === void 0 ? {} : _args$;
// Holds component state
var state = Object.assign({}, stateInit instanceof Function ? stateInit(options) : stateInit,
// Support plain objects for backwards compatibility
{
initialised: false
});
// keeps track of which props triggered an update
var changedProps = {};
// Component constructor
function comp(nodeElement) {
initStatic(nodeElement, options);
digest();
return comp;
}
var initStatic = function initStatic(nodeElement, options) {
initFn.call(comp, nodeElement, state, options);
state.initialised = true;
};
var digest = debounce(function () {
if (!state.initialised) {
return;
}
updateFn.call(comp, state, changedProps);
changedProps = {};
}, 1);
// Getter/setter methods
props.forEach(function (prop) {
comp[prop.name] = getSetProp(prop);
function getSetProp(_ref3) {
var prop = _ref3.name,
_ref3$triggerUpdate = _ref3.triggerUpdate,
redigest = _ref3$triggerUpdate === void 0 ? false : _ref3$triggerUpdate,
_ref3$onChange = _ref3.onChange,
onChange = _ref3$onChange === void 0 ? function (newVal, state) {} : _ref3$onChange,
_ref3$defaultVal = _ref3.defaultVal,
defaultVal = _ref3$defaultVal === void 0 ? null : _ref3$defaultVal;
return function (_) {
var curVal = state[prop];
if (!arguments.length) {
return curVal;
} // Getter mode
var val = _ === undefined ? defaultVal : _; // pick default if value passed is undefined
state[prop] = val;
onChange.call(comp, val, state, curVal);
// track changed props
!changedProps.hasOwnProperty(prop) && (changedProps[prop] = curVal);
if (redigest) {
digest();
}
return comp;
};
}
});
// Other methods
Object.keys(methods).forEach(function (methodName) {
comp[methodName] = function () {
var _methods$methodName;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return (_methods$methodName = methods[methodName]).call.apply(_methods$methodName, [comp, state].concat(args));
};
});
// Link aliases
Object.entries(aliases).forEach(function (_ref4) {
var _ref5 = _slicedToArray(_ref4, 2),
alias = _ref5[0],
target = _ref5[1];
return comp[alias] = comp[target];
});
// Reset all component props to their default value
comp.resetProps = function () {
props.forEach(function (prop) {
comp[prop.name](prop.defaultVal);
});
return comp;
};
//
comp.resetProps(); // Apply all prop defaults
state._rerender = digest; // Expose digest method
classMode && nodeElement && comp(nodeElement);
return comp;
};
}
return index;
}));
//# sourceMappingURL=kapsule.js.map

1
frontend/node_modules/kapsule/dist/kapsule.js.map generated vendored Normal file

File diff suppressed because one or more lines are too long

2
frontend/node_modules/kapsule/dist/kapsule.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

194
frontend/node_modules/kapsule/dist/kapsule.mjs generated vendored Normal file
View File

@@ -0,0 +1,194 @@
import debounce from 'lodash-es/debounce.js';
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
function _arrayWithHoles(r) {
if (Array.isArray(r)) return r;
}
function _classCallCheck(a, n) {
if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function");
}
function _createClass(e, r, t) {
return Object.defineProperty(e, "prototype", {
writable: false
}), e;
}
function _iterableToArrayLimit(r, l) {
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (null != t) {
var e,
n,
i,
u,
a = [],
f = true,
o = false;
try {
if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
} catch (r) {
o = true, n = r;
} finally {
try {
if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
} finally {
if (o) throw n;
}
}
return a;
}
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _slicedToArray(r, e) {
return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
var Prop = /*#__PURE__*/_createClass(function Prop(name, _ref) {
var _ref$default = _ref["default"],
defaultVal = _ref$default === void 0 ? null : _ref$default,
_ref$triggerUpdate = _ref.triggerUpdate,
triggerUpdate = _ref$triggerUpdate === void 0 ? true : _ref$triggerUpdate,
_ref$onChange = _ref.onChange,
onChange = _ref$onChange === void 0 ? function (newVal, state) {} : _ref$onChange;
_classCallCheck(this, Prop);
this.name = name;
this.defaultVal = defaultVal;
this.triggerUpdate = triggerUpdate;
this.onChange = onChange;
});
function index (_ref2) {
var _ref2$stateInit = _ref2.stateInit,
stateInit = _ref2$stateInit === void 0 ? function () {
return {};
} : _ref2$stateInit,
_ref2$props = _ref2.props,
rawProps = _ref2$props === void 0 ? {} : _ref2$props,
_ref2$methods = _ref2.methods,
methods = _ref2$methods === void 0 ? {} : _ref2$methods,
_ref2$aliases = _ref2.aliases,
aliases = _ref2$aliases === void 0 ? {} : _ref2$aliases,
_ref2$init = _ref2.init,
initFn = _ref2$init === void 0 ? function () {} : _ref2$init,
_ref2$update = _ref2.update,
updateFn = _ref2$update === void 0 ? function () {} : _ref2$update;
// Parse props into Prop instances
var props = Object.keys(rawProps).map(function (propName) {
return new Prop(propName, rawProps[propName]);
});
return function KapsuleComp() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var classMode = !!(this instanceof KapsuleComp ? this.constructor : void 0);
var nodeElement = classMode ? args.shift() : undefined;
var _args$ = args[0],
options = _args$ === void 0 ? {} : _args$;
// Holds component state
var state = Object.assign({}, stateInit instanceof Function ? stateInit(options) : stateInit,
// Support plain objects for backwards compatibility
{
initialised: false
});
// keeps track of which props triggered an update
var changedProps = {};
// Component constructor
function comp(nodeElement) {
initStatic(nodeElement, options);
digest();
return comp;
}
var initStatic = function initStatic(nodeElement, options) {
initFn.call(comp, nodeElement, state, options);
state.initialised = true;
};
var digest = debounce(function () {
if (!state.initialised) {
return;
}
updateFn.call(comp, state, changedProps);
changedProps = {};
}, 1);
// Getter/setter methods
props.forEach(function (prop) {
comp[prop.name] = getSetProp(prop);
function getSetProp(_ref3) {
var prop = _ref3.name,
_ref3$triggerUpdate = _ref3.triggerUpdate,
redigest = _ref3$triggerUpdate === void 0 ? false : _ref3$triggerUpdate,
_ref3$onChange = _ref3.onChange,
onChange = _ref3$onChange === void 0 ? function (newVal, state) {} : _ref3$onChange,
_ref3$defaultVal = _ref3.defaultVal,
defaultVal = _ref3$defaultVal === void 0 ? null : _ref3$defaultVal;
return function (_) {
var curVal = state[prop];
if (!arguments.length) {
return curVal;
} // Getter mode
var val = _ === undefined ? defaultVal : _; // pick default if value passed is undefined
state[prop] = val;
onChange.call(comp, val, state, curVal);
// track changed props
!changedProps.hasOwnProperty(prop) && (changedProps[prop] = curVal);
if (redigest) {
digest();
}
return comp;
};
}
});
// Other methods
Object.keys(methods).forEach(function (methodName) {
comp[methodName] = function () {
var _methods$methodName;
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return (_methods$methodName = methods[methodName]).call.apply(_methods$methodName, [comp, state].concat(args));
};
});
// Link aliases
Object.entries(aliases).forEach(function (_ref4) {
var _ref5 = _slicedToArray(_ref4, 2),
alias = _ref5[0],
target = _ref5[1];
return comp[alias] = comp[target];
});
// Reset all component props to their default value
comp.resetProps = function () {
props.forEach(function (prop) {
comp[prop.name](prop.defaultVal);
});
return comp;
};
//
comp.resetProps(); // Apply all prop defaults
state._rerender = digest; // Expose digest method
classMode && nodeElement && comp(nodeElement);
return comp;
};
}
export { index as default };

65
frontend/node_modules/kapsule/package.json generated vendored Normal file
View File

@@ -0,0 +1,65 @@
{
"name": "kapsule",
"version": "1.16.3",
"description": "A closure based Web Component library",
"type": "module",
"unpkg": "dist/kapsule.min.js",
"jsdelivr": "dist/kapsule.min.js",
"main": "dist/kapsule.mjs",
"module": "dist/kapsule.mjs",
"types": "dist/kapsule.d.ts",
"exports": {
"types": "./dist/kapsule.d.ts",
"umd": "./dist/kapsule.min.js",
"default": "./dist/kapsule.mjs"
},
"sideEffects": false,
"repository": {
"type": "git",
"url": "git+https://github.com/vasturiano/kapsule.git"
},
"keywords": [
"kapsule",
"web",
"component",
"lifecycle",
"reusable",
"closure",
"d3js"
],
"author": {
"name": "Vasco Asturiano",
"url": "https://github.com/vasturiano"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/vasturiano/kapsule/issues"
},
"homepage": "https://github.com/vasturiano/kapsule",
"scripts": {
"build": "rimraf dist && rollup -c",
"dev": "rollup -w -c",
"prepare": "npm run build"
},
"files": [
"dist/**/*"
],
"dependencies": {
"lodash-es": "4"
},
"devDependencies": {
"@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.3",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-terser": "^0.4.4",
"rimraf": "^6.0.1",
"rollup": "^4.36.0",
"rollup-plugin-dts": "^6.2.0",
"typescript": "^5.8.2"
},
"engines": {
"node": ">=12"
}
}