2281 lines
80 KiB
JavaScript
2281 lines
80 KiB
JavaScript
"use strict";
|
|
var KimaiHeatmap = (() => {
|
|
var __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __export = (target, all) => {
|
|
for (var name in all)
|
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
};
|
|
var __copyProps = (to, from, except, desc) => {
|
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
for (let key of __getOwnPropNames(from))
|
|
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
}
|
|
return to;
|
|
};
|
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
|
|
// assets/src/heatmap.ts
|
|
var heatmap_exports = {};
|
|
__export(heatmap_exports, {
|
|
init: () => init,
|
|
renderHeatmap: () => renderHeatmap
|
|
});
|
|
|
|
// node_modules/d3-selection/src/namespaces.js
|
|
var xhtml = "http://www.w3.org/1999/xhtml";
|
|
var namespaces_default = {
|
|
svg: "http://www.w3.org/2000/svg",
|
|
xhtml,
|
|
xlink: "http://www.w3.org/1999/xlink",
|
|
xml: "http://www.w3.org/XML/1998/namespace",
|
|
xmlns: "http://www.w3.org/2000/xmlns/"
|
|
};
|
|
|
|
// node_modules/d3-selection/src/namespace.js
|
|
function namespace_default(name) {
|
|
var prefix = name += "", i = prefix.indexOf(":");
|
|
if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
|
|
return namespaces_default.hasOwnProperty(prefix) ? { space: namespaces_default[prefix], local: name } : name;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/creator.js
|
|
function creatorInherit(name) {
|
|
return function() {
|
|
var document2 = this.ownerDocument, uri = this.namespaceURI;
|
|
return uri === xhtml && document2.documentElement.namespaceURI === xhtml ? document2.createElement(name) : document2.createElementNS(uri, name);
|
|
};
|
|
}
|
|
function creatorFixed(fullname) {
|
|
return function() {
|
|
return this.ownerDocument.createElementNS(fullname.space, fullname.local);
|
|
};
|
|
}
|
|
function creator_default(name) {
|
|
var fullname = namespace_default(name);
|
|
return (fullname.local ? creatorFixed : creatorInherit)(fullname);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selector.js
|
|
function none() {
|
|
}
|
|
function selector_default(selector) {
|
|
return selector == null ? none : function() {
|
|
return this.querySelector(selector);
|
|
};
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/select.js
|
|
function select_default(select) {
|
|
if (typeof select !== "function") select = selector_default(select);
|
|
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
|
|
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
|
|
if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
|
|
if ("__data__" in node) subnode.__data__ = node.__data__;
|
|
subgroup[i] = subnode;
|
|
}
|
|
}
|
|
}
|
|
return new Selection(subgroups, this._parents);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/array.js
|
|
function array(x) {
|
|
return x == null ? [] : Array.isArray(x) ? x : Array.from(x);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selectorAll.js
|
|
function empty() {
|
|
return [];
|
|
}
|
|
function selectorAll_default(selector) {
|
|
return selector == null ? empty : function() {
|
|
return this.querySelectorAll(selector);
|
|
};
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/selectAll.js
|
|
function arrayAll(select) {
|
|
return function() {
|
|
return array(select.apply(this, arguments));
|
|
};
|
|
}
|
|
function selectAll_default(select) {
|
|
if (typeof select === "function") select = arrayAll(select);
|
|
else select = selectorAll_default(select);
|
|
for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
|
|
for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
|
|
if (node = group[i]) {
|
|
subgroups.push(select.call(node, node.__data__, i, group));
|
|
parents.push(node);
|
|
}
|
|
}
|
|
}
|
|
return new Selection(subgroups, parents);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/matcher.js
|
|
function matcher_default(selector) {
|
|
return function() {
|
|
return this.matches(selector);
|
|
};
|
|
}
|
|
function childMatcher(selector) {
|
|
return function(node) {
|
|
return node.matches(selector);
|
|
};
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/selectChild.js
|
|
var find = Array.prototype.find;
|
|
function childFind(match) {
|
|
return function() {
|
|
return find.call(this.children, match);
|
|
};
|
|
}
|
|
function childFirst() {
|
|
return this.firstElementChild;
|
|
}
|
|
function selectChild_default(match) {
|
|
return this.select(match == null ? childFirst : childFind(typeof match === "function" ? match : childMatcher(match)));
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/selectChildren.js
|
|
var filter = Array.prototype.filter;
|
|
function children() {
|
|
return Array.from(this.children);
|
|
}
|
|
function childrenFilter(match) {
|
|
return function() {
|
|
return filter.call(this.children, match);
|
|
};
|
|
}
|
|
function selectChildren_default(match) {
|
|
return this.selectAll(match == null ? children : childrenFilter(typeof match === "function" ? match : childMatcher(match)));
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/filter.js
|
|
function filter_default(match) {
|
|
if (typeof match !== "function") match = matcher_default(match);
|
|
for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
|
|
for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
|
|
if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
|
|
subgroup.push(node);
|
|
}
|
|
}
|
|
}
|
|
return new Selection(subgroups, this._parents);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/sparse.js
|
|
function sparse_default(update) {
|
|
return new Array(update.length);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/enter.js
|
|
function enter_default() {
|
|
return new Selection(this._enter || this._groups.map(sparse_default), this._parents);
|
|
}
|
|
function EnterNode(parent, datum2) {
|
|
this.ownerDocument = parent.ownerDocument;
|
|
this.namespaceURI = parent.namespaceURI;
|
|
this._next = null;
|
|
this._parent = parent;
|
|
this.__data__ = datum2;
|
|
}
|
|
EnterNode.prototype = {
|
|
constructor: EnterNode,
|
|
appendChild: function(child) {
|
|
return this._parent.insertBefore(child, this._next);
|
|
},
|
|
insertBefore: function(child, next) {
|
|
return this._parent.insertBefore(child, next);
|
|
},
|
|
querySelector: function(selector) {
|
|
return this._parent.querySelector(selector);
|
|
},
|
|
querySelectorAll: function(selector) {
|
|
return this._parent.querySelectorAll(selector);
|
|
}
|
|
};
|
|
|
|
// node_modules/d3-selection/src/constant.js
|
|
function constant_default(x) {
|
|
return function() {
|
|
return x;
|
|
};
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/data.js
|
|
function bindIndex(parent, group, enter, update, exit, data) {
|
|
var i = 0, node, groupLength = group.length, dataLength = data.length;
|
|
for (; i < dataLength; ++i) {
|
|
if (node = group[i]) {
|
|
node.__data__ = data[i];
|
|
update[i] = node;
|
|
} else {
|
|
enter[i] = new EnterNode(parent, data[i]);
|
|
}
|
|
}
|
|
for (; i < groupLength; ++i) {
|
|
if (node = group[i]) {
|
|
exit[i] = node;
|
|
}
|
|
}
|
|
}
|
|
function bindKey(parent, group, enter, update, exit, data, key) {
|
|
var i, node, nodeByKeyValue = /* @__PURE__ */ new Map(), groupLength = group.length, dataLength = data.length, keyValues = new Array(groupLength), keyValue;
|
|
for (i = 0; i < groupLength; ++i) {
|
|
if (node = group[i]) {
|
|
keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + "";
|
|
if (nodeByKeyValue.has(keyValue)) {
|
|
exit[i] = node;
|
|
} else {
|
|
nodeByKeyValue.set(keyValue, node);
|
|
}
|
|
}
|
|
}
|
|
for (i = 0; i < dataLength; ++i) {
|
|
keyValue = key.call(parent, data[i], i, data) + "";
|
|
if (node = nodeByKeyValue.get(keyValue)) {
|
|
update[i] = node;
|
|
node.__data__ = data[i];
|
|
nodeByKeyValue.delete(keyValue);
|
|
} else {
|
|
enter[i] = new EnterNode(parent, data[i]);
|
|
}
|
|
}
|
|
for (i = 0; i < groupLength; ++i) {
|
|
if ((node = group[i]) && nodeByKeyValue.get(keyValues[i]) === node) {
|
|
exit[i] = node;
|
|
}
|
|
}
|
|
}
|
|
function datum(node) {
|
|
return node.__data__;
|
|
}
|
|
function data_default(value, key) {
|
|
if (!arguments.length) return Array.from(this, datum);
|
|
var bind = key ? bindKey : bindIndex, parents = this._parents, groups = this._groups;
|
|
if (typeof value !== "function") value = constant_default(value);
|
|
for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
|
|
var parent = parents[j], group = groups[j], groupLength = group.length, data = arraylike(value.call(parent, parent && parent.__data__, j, parents)), dataLength = data.length, enterGroup = enter[j] = new Array(dataLength), updateGroup = update[j] = new Array(dataLength), exitGroup = exit[j] = new Array(groupLength);
|
|
bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
|
|
for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
|
|
if (previous = enterGroup[i0]) {
|
|
if (i0 >= i1) i1 = i0 + 1;
|
|
while (!(next = updateGroup[i1]) && ++i1 < dataLength) ;
|
|
previous._next = next || null;
|
|
}
|
|
}
|
|
}
|
|
update = new Selection(update, parents);
|
|
update._enter = enter;
|
|
update._exit = exit;
|
|
return update;
|
|
}
|
|
function arraylike(data) {
|
|
return typeof data === "object" && "length" in data ? data : Array.from(data);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/exit.js
|
|
function exit_default() {
|
|
return new Selection(this._exit || this._groups.map(sparse_default), this._parents);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/join.js
|
|
function join_default(onenter, onupdate, onexit) {
|
|
var enter = this.enter(), update = this, exit = this.exit();
|
|
if (typeof onenter === "function") {
|
|
enter = onenter(enter);
|
|
if (enter) enter = enter.selection();
|
|
} else {
|
|
enter = enter.append(onenter + "");
|
|
}
|
|
if (onupdate != null) {
|
|
update = onupdate(update);
|
|
if (update) update = update.selection();
|
|
}
|
|
if (onexit == null) exit.remove();
|
|
else onexit(exit);
|
|
return enter && update ? enter.merge(update).order() : update;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/merge.js
|
|
function merge_default(context) {
|
|
var selection2 = context.selection ? context.selection() : context;
|
|
for (var groups0 = this._groups, groups1 = selection2._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
|
|
for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
|
|
if (node = group0[i] || group1[i]) {
|
|
merge[i] = node;
|
|
}
|
|
}
|
|
}
|
|
for (; j < m0; ++j) {
|
|
merges[j] = groups0[j];
|
|
}
|
|
return new Selection(merges, this._parents);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/order.js
|
|
function order_default() {
|
|
for (var groups = this._groups, j = -1, m = groups.length; ++j < m; ) {
|
|
for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {
|
|
if (node = group[i]) {
|
|
if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);
|
|
next = node;
|
|
}
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/sort.js
|
|
function sort_default(compare) {
|
|
if (!compare) compare = ascending;
|
|
function compareNode(a, b) {
|
|
return a && b ? compare(a.__data__, b.__data__) : !a - !b;
|
|
}
|
|
for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
|
|
for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
|
|
if (node = group[i]) {
|
|
sortgroup[i] = node;
|
|
}
|
|
}
|
|
sortgroup.sort(compareNode);
|
|
}
|
|
return new Selection(sortgroups, this._parents).order();
|
|
}
|
|
function ascending(a, b) {
|
|
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/call.js
|
|
function call_default() {
|
|
var callback = arguments[0];
|
|
arguments[0] = this;
|
|
callback.apply(null, arguments);
|
|
return this;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/nodes.js
|
|
function nodes_default() {
|
|
return Array.from(this);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/node.js
|
|
function node_default() {
|
|
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
|
|
for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
|
|
var node = group[i];
|
|
if (node) return node;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/size.js
|
|
function size_default() {
|
|
let size = 0;
|
|
for (const node of this) ++size;
|
|
return size;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/empty.js
|
|
function empty_default() {
|
|
return !this.node();
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/each.js
|
|
function each_default(callback) {
|
|
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
|
|
for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
|
|
if (node = group[i]) callback.call(node, node.__data__, i, group);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/attr.js
|
|
function attrRemove(name) {
|
|
return function() {
|
|
this.removeAttribute(name);
|
|
};
|
|
}
|
|
function attrRemoveNS(fullname) {
|
|
return function() {
|
|
this.removeAttributeNS(fullname.space, fullname.local);
|
|
};
|
|
}
|
|
function attrConstant(name, value) {
|
|
return function() {
|
|
this.setAttribute(name, value);
|
|
};
|
|
}
|
|
function attrConstantNS(fullname, value) {
|
|
return function() {
|
|
this.setAttributeNS(fullname.space, fullname.local, value);
|
|
};
|
|
}
|
|
function attrFunction(name, value) {
|
|
return function() {
|
|
var v = value.apply(this, arguments);
|
|
if (v == null) this.removeAttribute(name);
|
|
else this.setAttribute(name, v);
|
|
};
|
|
}
|
|
function attrFunctionNS(fullname, value) {
|
|
return function() {
|
|
var v = value.apply(this, arguments);
|
|
if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
|
|
else this.setAttributeNS(fullname.space, fullname.local, v);
|
|
};
|
|
}
|
|
function attr_default(name, value) {
|
|
var fullname = namespace_default(name);
|
|
if (arguments.length < 2) {
|
|
var node = this.node();
|
|
return fullname.local ? node.getAttributeNS(fullname.space, fullname.local) : node.getAttribute(fullname);
|
|
}
|
|
return this.each((value == null ? fullname.local ? attrRemoveNS : attrRemove : typeof value === "function" ? fullname.local ? attrFunctionNS : attrFunction : fullname.local ? attrConstantNS : attrConstant)(fullname, value));
|
|
}
|
|
|
|
// node_modules/d3-selection/src/window.js
|
|
function window_default(node) {
|
|
return node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/style.js
|
|
function styleRemove(name) {
|
|
return function() {
|
|
this.style.removeProperty(name);
|
|
};
|
|
}
|
|
function styleConstant(name, value, priority) {
|
|
return function() {
|
|
this.style.setProperty(name, value, priority);
|
|
};
|
|
}
|
|
function styleFunction(name, value, priority) {
|
|
return function() {
|
|
var v = value.apply(this, arguments);
|
|
if (v == null) this.style.removeProperty(name);
|
|
else this.style.setProperty(name, v, priority);
|
|
};
|
|
}
|
|
function style_default(name, value, priority) {
|
|
return arguments.length > 1 ? this.each((value == null ? styleRemove : typeof value === "function" ? styleFunction : styleConstant)(name, value, priority == null ? "" : priority)) : styleValue(this.node(), name);
|
|
}
|
|
function styleValue(node, name) {
|
|
return node.style.getPropertyValue(name) || window_default(node).getComputedStyle(node, null).getPropertyValue(name);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/property.js
|
|
function propertyRemove(name) {
|
|
return function() {
|
|
delete this[name];
|
|
};
|
|
}
|
|
function propertyConstant(name, value) {
|
|
return function() {
|
|
this[name] = value;
|
|
};
|
|
}
|
|
function propertyFunction(name, value) {
|
|
return function() {
|
|
var v = value.apply(this, arguments);
|
|
if (v == null) delete this[name];
|
|
else this[name] = v;
|
|
};
|
|
}
|
|
function property_default(name, value) {
|
|
return arguments.length > 1 ? this.each((value == null ? propertyRemove : typeof value === "function" ? propertyFunction : propertyConstant)(name, value)) : this.node()[name];
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/classed.js
|
|
function classArray(string) {
|
|
return string.trim().split(/^|\s+/);
|
|
}
|
|
function classList(node) {
|
|
return node.classList || new ClassList(node);
|
|
}
|
|
function ClassList(node) {
|
|
this._node = node;
|
|
this._names = classArray(node.getAttribute("class") || "");
|
|
}
|
|
ClassList.prototype = {
|
|
add: function(name) {
|
|
var i = this._names.indexOf(name);
|
|
if (i < 0) {
|
|
this._names.push(name);
|
|
this._node.setAttribute("class", this._names.join(" "));
|
|
}
|
|
},
|
|
remove: function(name) {
|
|
var i = this._names.indexOf(name);
|
|
if (i >= 0) {
|
|
this._names.splice(i, 1);
|
|
this._node.setAttribute("class", this._names.join(" "));
|
|
}
|
|
},
|
|
contains: function(name) {
|
|
return this._names.indexOf(name) >= 0;
|
|
}
|
|
};
|
|
function classedAdd(node, names) {
|
|
var list = classList(node), i = -1, n = names.length;
|
|
while (++i < n) list.add(names[i]);
|
|
}
|
|
function classedRemove(node, names) {
|
|
var list = classList(node), i = -1, n = names.length;
|
|
while (++i < n) list.remove(names[i]);
|
|
}
|
|
function classedTrue(names) {
|
|
return function() {
|
|
classedAdd(this, names);
|
|
};
|
|
}
|
|
function classedFalse(names) {
|
|
return function() {
|
|
classedRemove(this, names);
|
|
};
|
|
}
|
|
function classedFunction(names, value) {
|
|
return function() {
|
|
(value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
|
|
};
|
|
}
|
|
function classed_default(name, value) {
|
|
var names = classArray(name + "");
|
|
if (arguments.length < 2) {
|
|
var list = classList(this.node()), i = -1, n = names.length;
|
|
while (++i < n) if (!list.contains(names[i])) return false;
|
|
return true;
|
|
}
|
|
return this.each((typeof value === "function" ? classedFunction : value ? classedTrue : classedFalse)(names, value));
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/text.js
|
|
function textRemove() {
|
|
this.textContent = "";
|
|
}
|
|
function textConstant(value) {
|
|
return function() {
|
|
this.textContent = value;
|
|
};
|
|
}
|
|
function textFunction(value) {
|
|
return function() {
|
|
var v = value.apply(this, arguments);
|
|
this.textContent = v == null ? "" : v;
|
|
};
|
|
}
|
|
function text_default(value) {
|
|
return arguments.length ? this.each(value == null ? textRemove : (typeof value === "function" ? textFunction : textConstant)(value)) : this.node().textContent;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/html.js
|
|
function htmlRemove() {
|
|
this.innerHTML = "";
|
|
}
|
|
function htmlConstant(value) {
|
|
return function() {
|
|
this.innerHTML = value;
|
|
};
|
|
}
|
|
function htmlFunction(value) {
|
|
return function() {
|
|
var v = value.apply(this, arguments);
|
|
this.innerHTML = v == null ? "" : v;
|
|
};
|
|
}
|
|
function html_default(value) {
|
|
return arguments.length ? this.each(value == null ? htmlRemove : (typeof value === "function" ? htmlFunction : htmlConstant)(value)) : this.node().innerHTML;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/raise.js
|
|
function raise() {
|
|
if (this.nextSibling) this.parentNode.appendChild(this);
|
|
}
|
|
function raise_default() {
|
|
return this.each(raise);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/lower.js
|
|
function lower() {
|
|
if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
|
|
}
|
|
function lower_default() {
|
|
return this.each(lower);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/append.js
|
|
function append_default(name) {
|
|
var create = typeof name === "function" ? name : creator_default(name);
|
|
return this.select(function() {
|
|
return this.appendChild(create.apply(this, arguments));
|
|
});
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/insert.js
|
|
function constantNull() {
|
|
return null;
|
|
}
|
|
function insert_default(name, before) {
|
|
var create = typeof name === "function" ? name : creator_default(name), select = before == null ? constantNull : typeof before === "function" ? before : selector_default(before);
|
|
return this.select(function() {
|
|
return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
|
|
});
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/remove.js
|
|
function remove() {
|
|
var parent = this.parentNode;
|
|
if (parent) parent.removeChild(this);
|
|
}
|
|
function remove_default() {
|
|
return this.each(remove);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/clone.js
|
|
function selection_cloneShallow() {
|
|
var clone = this.cloneNode(false), parent = this.parentNode;
|
|
return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
|
|
}
|
|
function selection_cloneDeep() {
|
|
var clone = this.cloneNode(true), parent = this.parentNode;
|
|
return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
|
|
}
|
|
function clone_default(deep) {
|
|
return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/datum.js
|
|
function datum_default(value) {
|
|
return arguments.length ? this.property("__data__", value) : this.node().__data__;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/on.js
|
|
function contextListener(listener) {
|
|
return function(event) {
|
|
listener.call(this, event, this.__data__);
|
|
};
|
|
}
|
|
function parseTypenames(typenames) {
|
|
return typenames.trim().split(/^|\s+/).map(function(t) {
|
|
var name = "", i = t.indexOf(".");
|
|
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
|
|
return { type: t, name };
|
|
});
|
|
}
|
|
function onRemove(typename) {
|
|
return function() {
|
|
var on = this.__on;
|
|
if (!on) return;
|
|
for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
|
|
if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
|
|
this.removeEventListener(o.type, o.listener, o.options);
|
|
} else {
|
|
on[++i] = o;
|
|
}
|
|
}
|
|
if (++i) on.length = i;
|
|
else delete this.__on;
|
|
};
|
|
}
|
|
function onAdd(typename, value, options) {
|
|
return function() {
|
|
var on = this.__on, o, listener = contextListener(value);
|
|
if (on) for (var j = 0, m = on.length; j < m; ++j) {
|
|
if ((o = on[j]).type === typename.type && o.name === typename.name) {
|
|
this.removeEventListener(o.type, o.listener, o.options);
|
|
this.addEventListener(o.type, o.listener = listener, o.options = options);
|
|
o.value = value;
|
|
return;
|
|
}
|
|
}
|
|
this.addEventListener(typename.type, listener, options);
|
|
o = { type: typename.type, name: typename.name, value, listener, options };
|
|
if (!on) this.__on = [o];
|
|
else on.push(o);
|
|
};
|
|
}
|
|
function on_default(typename, value, options) {
|
|
var typenames = parseTypenames(typename + ""), i, n = typenames.length, t;
|
|
if (arguments.length < 2) {
|
|
var on = this.node().__on;
|
|
if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
|
|
for (i = 0, o = on[j]; i < n; ++i) {
|
|
if ((t = typenames[i]).type === o.type && t.name === o.name) {
|
|
return o.value;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
on = value ? onAdd : onRemove;
|
|
for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options));
|
|
return this;
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/dispatch.js
|
|
function dispatchEvent(node, type, params) {
|
|
var window2 = window_default(node), event = window2.CustomEvent;
|
|
if (typeof event === "function") {
|
|
event = new event(type, params);
|
|
} else {
|
|
event = window2.document.createEvent("Event");
|
|
if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
|
|
else event.initEvent(type, false, false);
|
|
}
|
|
node.dispatchEvent(event);
|
|
}
|
|
function dispatchConstant(type, params) {
|
|
return function() {
|
|
return dispatchEvent(this, type, params);
|
|
};
|
|
}
|
|
function dispatchFunction(type, params) {
|
|
return function() {
|
|
return dispatchEvent(this, type, params.apply(this, arguments));
|
|
};
|
|
}
|
|
function dispatch_default(type, params) {
|
|
return this.each((typeof params === "function" ? dispatchFunction : dispatchConstant)(type, params));
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/iterator.js
|
|
function* iterator_default() {
|
|
for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
|
|
for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
|
|
if (node = group[i]) yield node;
|
|
}
|
|
}
|
|
}
|
|
|
|
// node_modules/d3-selection/src/selection/index.js
|
|
var root = [null];
|
|
function Selection(groups, parents) {
|
|
this._groups = groups;
|
|
this._parents = parents;
|
|
}
|
|
function selection() {
|
|
return new Selection([[document.documentElement]], root);
|
|
}
|
|
function selection_selection() {
|
|
return this;
|
|
}
|
|
Selection.prototype = selection.prototype = {
|
|
constructor: Selection,
|
|
select: select_default,
|
|
selectAll: selectAll_default,
|
|
selectChild: selectChild_default,
|
|
selectChildren: selectChildren_default,
|
|
filter: filter_default,
|
|
data: data_default,
|
|
enter: enter_default,
|
|
exit: exit_default,
|
|
join: join_default,
|
|
merge: merge_default,
|
|
selection: selection_selection,
|
|
order: order_default,
|
|
sort: sort_default,
|
|
call: call_default,
|
|
nodes: nodes_default,
|
|
node: node_default,
|
|
size: size_default,
|
|
empty: empty_default,
|
|
each: each_default,
|
|
attr: attr_default,
|
|
style: style_default,
|
|
property: property_default,
|
|
classed: classed_default,
|
|
text: text_default,
|
|
html: html_default,
|
|
raise: raise_default,
|
|
lower: lower_default,
|
|
append: append_default,
|
|
insert: insert_default,
|
|
remove: remove_default,
|
|
clone: clone_default,
|
|
datum: datum_default,
|
|
on: on_default,
|
|
dispatch: dispatch_default,
|
|
[Symbol.iterator]: iterator_default
|
|
};
|
|
|
|
// node_modules/d3-selection/src/select.js
|
|
function select_default2(selector) {
|
|
return typeof selector === "string" ? new Selection([[document.querySelector(selector)]], [document.documentElement]) : new Selection([[selector]], root);
|
|
}
|
|
|
|
// node_modules/d3-array/src/ascending.js
|
|
function ascending2(a, b) {
|
|
return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
|
|
}
|
|
|
|
// node_modules/d3-array/src/descending.js
|
|
function descending(a, b) {
|
|
return a == null || b == null ? NaN : b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
|
|
}
|
|
|
|
// node_modules/d3-array/src/bisector.js
|
|
function bisector(f) {
|
|
let compare1, compare2, delta;
|
|
if (f.length !== 2) {
|
|
compare1 = ascending2;
|
|
compare2 = (d, x) => ascending2(f(d), x);
|
|
delta = (d, x) => f(d) - x;
|
|
} else {
|
|
compare1 = f === ascending2 || f === descending ? f : zero;
|
|
compare2 = f;
|
|
delta = f;
|
|
}
|
|
function left(a, x, lo = 0, hi = a.length) {
|
|
if (lo < hi) {
|
|
if (compare1(x, x) !== 0) return hi;
|
|
do {
|
|
const mid = lo + hi >>> 1;
|
|
if (compare2(a[mid], x) < 0) lo = mid + 1;
|
|
else hi = mid;
|
|
} while (lo < hi);
|
|
}
|
|
return lo;
|
|
}
|
|
function right(a, x, lo = 0, hi = a.length) {
|
|
if (lo < hi) {
|
|
if (compare1(x, x) !== 0) return hi;
|
|
do {
|
|
const mid = lo + hi >>> 1;
|
|
if (compare2(a[mid], x) <= 0) lo = mid + 1;
|
|
else hi = mid;
|
|
} while (lo < hi);
|
|
}
|
|
return lo;
|
|
}
|
|
function center(a, x, lo = 0, hi = a.length) {
|
|
const i = left(a, x, lo, hi - 1);
|
|
return i > lo && delta(a[i - 1], x) > -delta(a[i], x) ? i - 1 : i;
|
|
}
|
|
return { left, center, right };
|
|
}
|
|
function zero() {
|
|
return 0;
|
|
}
|
|
|
|
// node_modules/d3-array/src/number.js
|
|
function number(x) {
|
|
return x === null ? NaN : +x;
|
|
}
|
|
|
|
// node_modules/d3-array/src/bisect.js
|
|
var ascendingBisect = bisector(ascending2);
|
|
var bisectRight = ascendingBisect.right;
|
|
var bisectLeft = ascendingBisect.left;
|
|
var bisectCenter = bisector(number).center;
|
|
var bisect_default = bisectRight;
|
|
|
|
// node_modules/d3-array/src/ticks.js
|
|
var e10 = Math.sqrt(50);
|
|
var e5 = Math.sqrt(10);
|
|
var e2 = Math.sqrt(2);
|
|
function tickSpec(start, stop, count) {
|
|
const step = (stop - start) / Math.max(0, count), power = Math.floor(Math.log10(step)), error = step / Math.pow(10, power), factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1;
|
|
let i1, i2, inc;
|
|
if (power < 0) {
|
|
inc = Math.pow(10, -power) / factor;
|
|
i1 = Math.round(start * inc);
|
|
i2 = Math.round(stop * inc);
|
|
if (i1 / inc < start) ++i1;
|
|
if (i2 / inc > stop) --i2;
|
|
inc = -inc;
|
|
} else {
|
|
inc = Math.pow(10, power) * factor;
|
|
i1 = Math.round(start / inc);
|
|
i2 = Math.round(stop / inc);
|
|
if (i1 * inc < start) ++i1;
|
|
if (i2 * inc > stop) --i2;
|
|
}
|
|
if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2);
|
|
return [i1, i2, inc];
|
|
}
|
|
function ticks(start, stop, count) {
|
|
stop = +stop, start = +start, count = +count;
|
|
if (!(count > 0)) return [];
|
|
if (start === stop) return [start];
|
|
const reverse = stop < start, [i1, i2, inc] = reverse ? tickSpec(stop, start, count) : tickSpec(start, stop, count);
|
|
if (!(i2 >= i1)) return [];
|
|
const n = i2 - i1 + 1, ticks2 = new Array(n);
|
|
if (reverse) {
|
|
if (inc < 0) for (let i = 0; i < n; ++i) ticks2[i] = (i2 - i) / -inc;
|
|
else for (let i = 0; i < n; ++i) ticks2[i] = (i2 - i) * inc;
|
|
} else {
|
|
if (inc < 0) for (let i = 0; i < n; ++i) ticks2[i] = (i1 + i) / -inc;
|
|
else for (let i = 0; i < n; ++i) ticks2[i] = (i1 + i) * inc;
|
|
}
|
|
return ticks2;
|
|
}
|
|
function tickIncrement(start, stop, count) {
|
|
stop = +stop, start = +start, count = +count;
|
|
return tickSpec(start, stop, count)[2];
|
|
}
|
|
function tickStep(start, stop, count) {
|
|
stop = +stop, start = +start, count = +count;
|
|
const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count);
|
|
return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc);
|
|
}
|
|
|
|
// node_modules/d3-array/src/max.js
|
|
function max(values, valueof) {
|
|
let max2;
|
|
if (valueof === void 0) {
|
|
for (const value of values) {
|
|
if (value != null && (max2 < value || max2 === void 0 && value >= value)) {
|
|
max2 = value;
|
|
}
|
|
}
|
|
} else {
|
|
let index = -1;
|
|
for (let value of values) {
|
|
if ((value = valueof(value, ++index, values)) != null && (max2 < value || max2 === void 0 && value >= value)) {
|
|
max2 = value;
|
|
}
|
|
}
|
|
}
|
|
return max2;
|
|
}
|
|
|
|
// node_modules/d3-scale/src/init.js
|
|
function initRange(domain, range) {
|
|
switch (arguments.length) {
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
this.range(domain);
|
|
break;
|
|
default:
|
|
this.range(range).domain(domain);
|
|
break;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// node_modules/d3-format/src/formatDecimal.js
|
|
function formatDecimal_default(x) {
|
|
return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10);
|
|
}
|
|
function formatDecimalParts(x, p) {
|
|
if (!isFinite(x) || x === 0) return null;
|
|
var i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e"), coefficient = x.slice(0, i);
|
|
return [
|
|
coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
|
|
+x.slice(i + 1)
|
|
];
|
|
}
|
|
|
|
// node_modules/d3-format/src/exponent.js
|
|
function exponent_default(x) {
|
|
return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN;
|
|
}
|
|
|
|
// node_modules/d3-format/src/formatGroup.js
|
|
function formatGroup_default(grouping, thousands) {
|
|
return function(value, width) {
|
|
var i = value.length, t = [], j = 0, g = grouping[0], length = 0;
|
|
while (i > 0 && g > 0) {
|
|
if (length + g + 1 > width) g = Math.max(1, width - length);
|
|
t.push(value.substring(i -= g, i + g));
|
|
if ((length += g + 1) > width) break;
|
|
g = grouping[j = (j + 1) % grouping.length];
|
|
}
|
|
return t.reverse().join(thousands);
|
|
};
|
|
}
|
|
|
|
// node_modules/d3-format/src/formatNumerals.js
|
|
function formatNumerals_default(numerals) {
|
|
return function(value) {
|
|
return value.replace(/[0-9]/g, function(i) {
|
|
return numerals[+i];
|
|
});
|
|
};
|
|
}
|
|
|
|
// node_modules/d3-format/src/formatSpecifier.js
|
|
var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;
|
|
function formatSpecifier(specifier) {
|
|
if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
|
|
var match;
|
|
return new FormatSpecifier({
|
|
fill: match[1],
|
|
align: match[2],
|
|
sign: match[3],
|
|
symbol: match[4],
|
|
zero: match[5],
|
|
width: match[6],
|
|
comma: match[7],
|
|
precision: match[8] && match[8].slice(1),
|
|
trim: match[9],
|
|
type: match[10]
|
|
});
|
|
}
|
|
formatSpecifier.prototype = FormatSpecifier.prototype;
|
|
function FormatSpecifier(specifier) {
|
|
this.fill = specifier.fill === void 0 ? " " : specifier.fill + "";
|
|
this.align = specifier.align === void 0 ? ">" : specifier.align + "";
|
|
this.sign = specifier.sign === void 0 ? "-" : specifier.sign + "";
|
|
this.symbol = specifier.symbol === void 0 ? "" : specifier.symbol + "";
|
|
this.zero = !!specifier.zero;
|
|
this.width = specifier.width === void 0 ? void 0 : +specifier.width;
|
|
this.comma = !!specifier.comma;
|
|
this.precision = specifier.precision === void 0 ? void 0 : +specifier.precision;
|
|
this.trim = !!specifier.trim;
|
|
this.type = specifier.type === void 0 ? "" : specifier.type + "";
|
|
}
|
|
FormatSpecifier.prototype.toString = function() {
|
|
return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === void 0 ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === void 0 ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type;
|
|
};
|
|
|
|
// node_modules/d3-format/src/formatTrim.js
|
|
function formatTrim_default(s) {
|
|
out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) {
|
|
switch (s[i]) {
|
|
case ".":
|
|
i0 = i1 = i;
|
|
break;
|
|
case "0":
|
|
if (i0 === 0) i0 = i;
|
|
i1 = i;
|
|
break;
|
|
default:
|
|
if (!+s[i]) break out;
|
|
if (i0 > 0) i0 = 0;
|
|
break;
|
|
}
|
|
}
|
|
return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s;
|
|
}
|
|
|
|
// node_modules/d3-format/src/formatPrefixAuto.js
|
|
var prefixExponent;
|
|
function formatPrefixAuto_default(x, p) {
|
|
var d = formatDecimalParts(x, p);
|
|
if (!d) return prefixExponent = void 0, x.toPrecision(p);
|
|
var coefficient = d[0], exponent = d[1], i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, n = coefficient.length;
|
|
return i === n ? coefficient : i > n ? coefficient + new Array(i - n + 1).join("0") : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0];
|
|
}
|
|
|
|
// node_modules/d3-format/src/formatRounded.js
|
|
function formatRounded_default(x, p) {
|
|
var d = formatDecimalParts(x, p);
|
|
if (!d) return x + "";
|
|
var coefficient = d[0], exponent = d[1];
|
|
return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0");
|
|
}
|
|
|
|
// node_modules/d3-format/src/formatTypes.js
|
|
var formatTypes_default = {
|
|
"%": (x, p) => (x * 100).toFixed(p),
|
|
"b": (x) => Math.round(x).toString(2),
|
|
"c": (x) => x + "",
|
|
"d": formatDecimal_default,
|
|
"e": (x, p) => x.toExponential(p),
|
|
"f": (x, p) => x.toFixed(p),
|
|
"g": (x, p) => x.toPrecision(p),
|
|
"o": (x) => Math.round(x).toString(8),
|
|
"p": (x, p) => formatRounded_default(x * 100, p),
|
|
"r": formatRounded_default,
|
|
"s": formatPrefixAuto_default,
|
|
"X": (x) => Math.round(x).toString(16).toUpperCase(),
|
|
"x": (x) => Math.round(x).toString(16)
|
|
};
|
|
|
|
// node_modules/d3-format/src/identity.js
|
|
function identity_default(x) {
|
|
return x;
|
|
}
|
|
|
|
// node_modules/d3-format/src/locale.js
|
|
var map = Array.prototype.map;
|
|
var prefixes = ["y", "z", "a", "f", "p", "n", "\xB5", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"];
|
|
function locale_default(locale3) {
|
|
var group = locale3.grouping === void 0 || locale3.thousands === void 0 ? identity_default : formatGroup_default(map.call(locale3.grouping, Number), locale3.thousands + ""), currencyPrefix = locale3.currency === void 0 ? "" : locale3.currency[0] + "", currencySuffix = locale3.currency === void 0 ? "" : locale3.currency[1] + "", decimal = locale3.decimal === void 0 ? "." : locale3.decimal + "", numerals = locale3.numerals === void 0 ? identity_default : formatNumerals_default(map.call(locale3.numerals, String)), percent = locale3.percent === void 0 ? "%" : locale3.percent + "", minus = locale3.minus === void 0 ? "\u2212" : locale3.minus + "", nan = locale3.nan === void 0 ? "NaN" : locale3.nan + "";
|
|
function newFormat(specifier, options) {
|
|
specifier = formatSpecifier(specifier);
|
|
var fill = specifier.fill, align = specifier.align, sign = specifier.sign, symbol = specifier.symbol, zero2 = specifier.zero, width = specifier.width, comma = specifier.comma, precision = specifier.precision, trim = specifier.trim, type = specifier.type;
|
|
if (type === "n") comma = true, type = "g";
|
|
else if (!formatTypes_default[type]) precision === void 0 && (precision = 12), trim = true, type = "g";
|
|
if (zero2 || fill === "0" && align === "=") zero2 = true, fill = "0", align = "=";
|
|
var prefix = (options && options.prefix !== void 0 ? options.prefix : "") + (symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : ""), suffix = (symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : "") + (options && options.suffix !== void 0 ? options.suffix : "");
|
|
var formatType = formatTypes_default[type], maybeSuffix = /[defgprs%]/.test(type);
|
|
precision = precision === void 0 ? 6 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) : Math.max(0, Math.min(20, precision));
|
|
function format2(value) {
|
|
var valuePrefix = prefix, valueSuffix = suffix, i, n, c;
|
|
if (type === "c") {
|
|
valueSuffix = formatType(value) + valueSuffix;
|
|
value = "";
|
|
} else {
|
|
value = +value;
|
|
var valueNegative = value < 0 || 1 / value < 0;
|
|
value = isNaN(value) ? nan : formatType(Math.abs(value), precision);
|
|
if (trim) value = formatTrim_default(value);
|
|
if (valueNegative && +value === 0 && sign !== "+") valueNegative = false;
|
|
valuePrefix = (valueNegative ? sign === "(" ? sign : minus : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
|
|
valueSuffix = (type === "s" && !isNaN(value) && prefixExponent !== void 0 ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : "");
|
|
if (maybeSuffix) {
|
|
i = -1, n = value.length;
|
|
while (++i < n) {
|
|
if (c = value.charCodeAt(i), 48 > c || c > 57) {
|
|
valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
|
|
value = value.slice(0, i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (comma && !zero2) value = group(value, Infinity);
|
|
var length = valuePrefix.length + value.length + valueSuffix.length, padding = length < width ? new Array(width - length + 1).join(fill) : "";
|
|
if (comma && zero2) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
|
|
switch (align) {
|
|
case "<":
|
|
value = valuePrefix + value + valueSuffix + padding;
|
|
break;
|
|
case "=":
|
|
value = valuePrefix + padding + value + valueSuffix;
|
|
break;
|
|
case "^":
|
|
value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length);
|
|
break;
|
|
default:
|
|
value = padding + valuePrefix + value + valueSuffix;
|
|
break;
|
|
}
|
|
return numerals(value);
|
|
}
|
|
format2.toString = function() {
|
|
return specifier + "";
|
|
};
|
|
return format2;
|
|
}
|
|
function formatPrefix2(specifier, value) {
|
|
var e = Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3, k = Math.pow(10, -e), f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier), { suffix: prefixes[8 + e / 3] });
|
|
return function(value2) {
|
|
return f(k * value2);
|
|
};
|
|
}
|
|
return {
|
|
format: newFormat,
|
|
formatPrefix: formatPrefix2
|
|
};
|
|
}
|
|
|
|
// node_modules/d3-format/src/defaultLocale.js
|
|
var locale;
|
|
var format;
|
|
var formatPrefix;
|
|
defaultLocale({
|
|
thousands: ",",
|
|
grouping: [3],
|
|
currency: ["$", ""]
|
|
});
|
|
function defaultLocale(definition) {
|
|
locale = locale_default(definition);
|
|
format = locale.format;
|
|
formatPrefix = locale.formatPrefix;
|
|
return locale;
|
|
}
|
|
|
|
// node_modules/d3-format/src/precisionFixed.js
|
|
function precisionFixed_default(step) {
|
|
return Math.max(0, -exponent_default(Math.abs(step)));
|
|
}
|
|
|
|
// node_modules/d3-format/src/precisionPrefix.js
|
|
function precisionPrefix_default(step, value) {
|
|
return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent_default(value) / 3))) * 3 - exponent_default(Math.abs(step)));
|
|
}
|
|
|
|
// node_modules/d3-format/src/precisionRound.js
|
|
function precisionRound_default(step, max2) {
|
|
step = Math.abs(step), max2 = Math.abs(max2) - step;
|
|
return Math.max(0, exponent_default(max2) - exponent_default(step)) + 1;
|
|
}
|
|
|
|
// node_modules/d3-scale/src/tickFormat.js
|
|
function tickFormat(start, stop, count, specifier) {
|
|
var step = tickStep(start, stop, count), precision;
|
|
specifier = formatSpecifier(specifier == null ? ",f" : specifier);
|
|
switch (specifier.type) {
|
|
case "s": {
|
|
var value = Math.max(Math.abs(start), Math.abs(stop));
|
|
if (specifier.precision == null && !isNaN(precision = precisionPrefix_default(step, value))) specifier.precision = precision;
|
|
return formatPrefix(specifier, value);
|
|
}
|
|
case "":
|
|
case "e":
|
|
case "g":
|
|
case "p":
|
|
case "r": {
|
|
if (specifier.precision == null && !isNaN(precision = precisionRound_default(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
|
|
break;
|
|
}
|
|
case "f":
|
|
case "%": {
|
|
if (specifier.precision == null && !isNaN(precision = precisionFixed_default(step))) specifier.precision = precision - (specifier.type === "%") * 2;
|
|
break;
|
|
}
|
|
}
|
|
return format(specifier);
|
|
}
|
|
|
|
// node_modules/d3-scale/src/linear.js
|
|
function linearish(scale) {
|
|
var domain = scale.domain;
|
|
scale.ticks = function(count) {
|
|
var d = domain();
|
|
return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
|
|
};
|
|
scale.tickFormat = function(count, specifier) {
|
|
var d = domain();
|
|
return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);
|
|
};
|
|
scale.nice = function(count) {
|
|
if (count == null) count = 10;
|
|
var d = domain();
|
|
var i0 = 0;
|
|
var i1 = d.length - 1;
|
|
var start = d[i0];
|
|
var stop = d[i1];
|
|
var prestep;
|
|
var step;
|
|
var maxIter = 10;
|
|
if (stop < start) {
|
|
step = start, start = stop, stop = step;
|
|
step = i0, i0 = i1, i1 = step;
|
|
}
|
|
while (maxIter-- > 0) {
|
|
step = tickIncrement(start, stop, count);
|
|
if (step === prestep) {
|
|
d[i0] = start;
|
|
d[i1] = stop;
|
|
return domain(d);
|
|
} else if (step > 0) {
|
|
start = Math.floor(start / step) * step;
|
|
stop = Math.ceil(stop / step) * step;
|
|
} else if (step < 0) {
|
|
start = Math.ceil(start * step) / step;
|
|
stop = Math.floor(stop * step) / step;
|
|
} else {
|
|
break;
|
|
}
|
|
prestep = step;
|
|
}
|
|
return scale;
|
|
};
|
|
return scale;
|
|
}
|
|
|
|
// node_modules/d3-scale/src/quantize.js
|
|
function quantize() {
|
|
var x0 = 0, x1 = 1, n = 1, domain = [0.5], range = [0, 1], unknown;
|
|
function scale(x) {
|
|
return x != null && x <= x ? range[bisect_default(domain, x, 0, n)] : unknown;
|
|
}
|
|
function rescale() {
|
|
var i = -1;
|
|
domain = new Array(n);
|
|
while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
|
|
return scale;
|
|
}
|
|
scale.domain = function(_) {
|
|
return arguments.length ? ([x0, x1] = _, x0 = +x0, x1 = +x1, rescale()) : [x0, x1];
|
|
};
|
|
scale.range = function(_) {
|
|
return arguments.length ? (n = (range = Array.from(_)).length - 1, rescale()) : range.slice();
|
|
};
|
|
scale.invertExtent = function(y) {
|
|
var i = range.indexOf(y);
|
|
return i < 0 ? [NaN, NaN] : i < 1 ? [x0, domain[0]] : i >= n ? [domain[n - 1], x1] : [domain[i - 1], domain[i]];
|
|
};
|
|
scale.unknown = function(_) {
|
|
return arguments.length ? (unknown = _, scale) : scale;
|
|
};
|
|
scale.thresholds = function() {
|
|
return domain.slice();
|
|
};
|
|
scale.copy = function() {
|
|
return quantize().domain([x0, x1]).range(range).unknown(unknown);
|
|
};
|
|
return initRange.apply(linearish(scale), arguments);
|
|
}
|
|
|
|
// node_modules/d3-time/src/interval.js
|
|
var t0 = /* @__PURE__ */ new Date();
|
|
var t1 = /* @__PURE__ */ new Date();
|
|
function timeInterval(floori, offseti, count, field) {
|
|
function interval(date) {
|
|
return floori(date = arguments.length === 0 ? /* @__PURE__ */ new Date() : /* @__PURE__ */ new Date(+date)), date;
|
|
}
|
|
interval.floor = (date) => {
|
|
return floori(date = /* @__PURE__ */ new Date(+date)), date;
|
|
};
|
|
interval.ceil = (date) => {
|
|
return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
|
|
};
|
|
interval.round = (date) => {
|
|
const d0 = interval(date), d1 = interval.ceil(date);
|
|
return date - d0 < d1 - date ? d0 : d1;
|
|
};
|
|
interval.offset = (date, step) => {
|
|
return offseti(date = /* @__PURE__ */ new Date(+date), step == null ? 1 : Math.floor(step)), date;
|
|
};
|
|
interval.range = (start, stop, step) => {
|
|
const range = [];
|
|
start = interval.ceil(start);
|
|
step = step == null ? 1 : Math.floor(step);
|
|
if (!(start < stop) || !(step > 0)) return range;
|
|
let previous;
|
|
do
|
|
range.push(previous = /* @__PURE__ */ new Date(+start)), offseti(start, step), floori(start);
|
|
while (previous < start && start < stop);
|
|
return range;
|
|
};
|
|
interval.filter = (test) => {
|
|
return timeInterval((date) => {
|
|
if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
|
|
}, (date, step) => {
|
|
if (date >= date) {
|
|
if (step < 0) while (++step <= 0) {
|
|
while (offseti(date, -1), !test(date)) {
|
|
}
|
|
}
|
|
else while (--step >= 0) {
|
|
while (offseti(date, 1), !test(date)) {
|
|
}
|
|
}
|
|
}
|
|
});
|
|
};
|
|
if (count) {
|
|
interval.count = (start, end) => {
|
|
t0.setTime(+start), t1.setTime(+end);
|
|
floori(t0), floori(t1);
|
|
return Math.floor(count(t0, t1));
|
|
};
|
|
interval.every = (step) => {
|
|
step = Math.floor(step);
|
|
return !isFinite(step) || !(step > 0) ? null : !(step > 1) ? interval : interval.filter(field ? (d) => field(d) % step === 0 : (d) => interval.count(0, d) % step === 0);
|
|
};
|
|
}
|
|
return interval;
|
|
}
|
|
|
|
// node_modules/d3-time/src/duration.js
|
|
var durationSecond = 1e3;
|
|
var durationMinute = durationSecond * 60;
|
|
var durationHour = durationMinute * 60;
|
|
var durationDay = durationHour * 24;
|
|
var durationWeek = durationDay * 7;
|
|
var durationMonth = durationDay * 30;
|
|
var durationYear = durationDay * 365;
|
|
|
|
// node_modules/d3-time/src/day.js
|
|
var timeDay = timeInterval(
|
|
(date) => date.setHours(0, 0, 0, 0),
|
|
(date, step) => date.setDate(date.getDate() + step),
|
|
(start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay,
|
|
(date) => date.getDate() - 1
|
|
);
|
|
var timeDays = timeDay.range;
|
|
var utcDay = timeInterval((date) => {
|
|
date.setUTCHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setUTCDate(date.getUTCDate() + step);
|
|
}, (start, end) => {
|
|
return (end - start) / durationDay;
|
|
}, (date) => {
|
|
return date.getUTCDate() - 1;
|
|
});
|
|
var utcDays = utcDay.range;
|
|
var unixDay = timeInterval((date) => {
|
|
date.setUTCHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setUTCDate(date.getUTCDate() + step);
|
|
}, (start, end) => {
|
|
return (end - start) / durationDay;
|
|
}, (date) => {
|
|
return Math.floor(date / durationDay);
|
|
});
|
|
var unixDays = unixDay.range;
|
|
|
|
// node_modules/d3-time/src/week.js
|
|
function timeWeekday(i) {
|
|
return timeInterval((date) => {
|
|
date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
|
|
date.setHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setDate(date.getDate() + step * 7);
|
|
}, (start, end) => {
|
|
return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
|
|
});
|
|
}
|
|
var timeSunday = timeWeekday(0);
|
|
var timeMonday = timeWeekday(1);
|
|
var timeTuesday = timeWeekday(2);
|
|
var timeWednesday = timeWeekday(3);
|
|
var timeThursday = timeWeekday(4);
|
|
var timeFriday = timeWeekday(5);
|
|
var timeSaturday = timeWeekday(6);
|
|
var timeSundays = timeSunday.range;
|
|
var timeMondays = timeMonday.range;
|
|
var timeTuesdays = timeTuesday.range;
|
|
var timeWednesdays = timeWednesday.range;
|
|
var timeThursdays = timeThursday.range;
|
|
var timeFridays = timeFriday.range;
|
|
var timeSaturdays = timeSaturday.range;
|
|
function utcWeekday(i) {
|
|
return timeInterval((date) => {
|
|
date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
|
|
date.setUTCHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setUTCDate(date.getUTCDate() + step * 7);
|
|
}, (start, end) => {
|
|
return (end - start) / durationWeek;
|
|
});
|
|
}
|
|
var utcSunday = utcWeekday(0);
|
|
var utcMonday = utcWeekday(1);
|
|
var utcTuesday = utcWeekday(2);
|
|
var utcWednesday = utcWeekday(3);
|
|
var utcThursday = utcWeekday(4);
|
|
var utcFriday = utcWeekday(5);
|
|
var utcSaturday = utcWeekday(6);
|
|
var utcSundays = utcSunday.range;
|
|
var utcMondays = utcMonday.range;
|
|
var utcTuesdays = utcTuesday.range;
|
|
var utcWednesdays = utcWednesday.range;
|
|
var utcThursdays = utcThursday.range;
|
|
var utcFridays = utcFriday.range;
|
|
var utcSaturdays = utcSaturday.range;
|
|
|
|
// node_modules/d3-time/src/month.js
|
|
var timeMonth = timeInterval((date) => {
|
|
date.setDate(1);
|
|
date.setHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setMonth(date.getMonth() + step);
|
|
}, (start, end) => {
|
|
return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
|
|
}, (date) => {
|
|
return date.getMonth();
|
|
});
|
|
var timeMonths = timeMonth.range;
|
|
var utcMonth = timeInterval((date) => {
|
|
date.setUTCDate(1);
|
|
date.setUTCHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setUTCMonth(date.getUTCMonth() + step);
|
|
}, (start, end) => {
|
|
return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
|
|
}, (date) => {
|
|
return date.getUTCMonth();
|
|
});
|
|
var utcMonths = utcMonth.range;
|
|
|
|
// node_modules/d3-time/src/year.js
|
|
var timeYear = timeInterval((date) => {
|
|
date.setMonth(0, 1);
|
|
date.setHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setFullYear(date.getFullYear() + step);
|
|
}, (start, end) => {
|
|
return end.getFullYear() - start.getFullYear();
|
|
}, (date) => {
|
|
return date.getFullYear();
|
|
});
|
|
timeYear.every = (k) => {
|
|
return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {
|
|
date.setFullYear(Math.floor(date.getFullYear() / k) * k);
|
|
date.setMonth(0, 1);
|
|
date.setHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setFullYear(date.getFullYear() + step * k);
|
|
});
|
|
};
|
|
var timeYears = timeYear.range;
|
|
var utcYear = timeInterval((date) => {
|
|
date.setUTCMonth(0, 1);
|
|
date.setUTCHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setUTCFullYear(date.getUTCFullYear() + step);
|
|
}, (start, end) => {
|
|
return end.getUTCFullYear() - start.getUTCFullYear();
|
|
}, (date) => {
|
|
return date.getUTCFullYear();
|
|
});
|
|
utcYear.every = (k) => {
|
|
return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval((date) => {
|
|
date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
|
|
date.setUTCMonth(0, 1);
|
|
date.setUTCHours(0, 0, 0, 0);
|
|
}, (date, step) => {
|
|
date.setUTCFullYear(date.getUTCFullYear() + step * k);
|
|
});
|
|
};
|
|
var utcYears = utcYear.range;
|
|
|
|
// node_modules/d3-time-format/src/locale.js
|
|
function localDate(d) {
|
|
if (0 <= d.y && d.y < 100) {
|
|
var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
|
|
date.setFullYear(d.y);
|
|
return date;
|
|
}
|
|
return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
|
|
}
|
|
function utcDate(d) {
|
|
if (0 <= d.y && d.y < 100) {
|
|
var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
|
|
date.setUTCFullYear(d.y);
|
|
return date;
|
|
}
|
|
return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
|
|
}
|
|
function newDate(y, m, d) {
|
|
return { y, m, d, H: 0, M: 0, S: 0, L: 0 };
|
|
}
|
|
function formatLocale(locale3) {
|
|
var locale_dateTime = locale3.dateTime, locale_date = locale3.date, locale_time = locale3.time, locale_periods = locale3.periods, locale_weekdays = locale3.days, locale_shortWeekdays = locale3.shortDays, locale_months = locale3.months, locale_shortMonths = locale3.shortMonths;
|
|
var periodRe = formatRe(locale_periods), periodLookup = formatLookup(locale_periods), weekdayRe = formatRe(locale_weekdays), weekdayLookup = formatLookup(locale_weekdays), shortWeekdayRe = formatRe(locale_shortWeekdays), shortWeekdayLookup = formatLookup(locale_shortWeekdays), monthRe = formatRe(locale_months), monthLookup = formatLookup(locale_months), shortMonthRe = formatRe(locale_shortMonths), shortMonthLookup = formatLookup(locale_shortMonths);
|
|
var formats = {
|
|
"a": formatShortWeekday,
|
|
"A": formatWeekday,
|
|
"b": formatShortMonth,
|
|
"B": formatMonth,
|
|
"c": null,
|
|
"d": formatDayOfMonth,
|
|
"e": formatDayOfMonth,
|
|
"f": formatMicroseconds,
|
|
"g": formatYearISO,
|
|
"G": formatFullYearISO,
|
|
"H": formatHour24,
|
|
"I": formatHour12,
|
|
"j": formatDayOfYear,
|
|
"L": formatMilliseconds,
|
|
"m": formatMonthNumber,
|
|
"M": formatMinutes,
|
|
"p": formatPeriod,
|
|
"q": formatQuarter,
|
|
"Q": formatUnixTimestamp,
|
|
"s": formatUnixTimestampSeconds,
|
|
"S": formatSeconds,
|
|
"u": formatWeekdayNumberMonday,
|
|
"U": formatWeekNumberSunday,
|
|
"V": formatWeekNumberISO,
|
|
"w": formatWeekdayNumberSunday,
|
|
"W": formatWeekNumberMonday,
|
|
"x": null,
|
|
"X": null,
|
|
"y": formatYear,
|
|
"Y": formatFullYear,
|
|
"Z": formatZone,
|
|
"%": formatLiteralPercent
|
|
};
|
|
var utcFormats = {
|
|
"a": formatUTCShortWeekday,
|
|
"A": formatUTCWeekday,
|
|
"b": formatUTCShortMonth,
|
|
"B": formatUTCMonth,
|
|
"c": null,
|
|
"d": formatUTCDayOfMonth,
|
|
"e": formatUTCDayOfMonth,
|
|
"f": formatUTCMicroseconds,
|
|
"g": formatUTCYearISO,
|
|
"G": formatUTCFullYearISO,
|
|
"H": formatUTCHour24,
|
|
"I": formatUTCHour12,
|
|
"j": formatUTCDayOfYear,
|
|
"L": formatUTCMilliseconds,
|
|
"m": formatUTCMonthNumber,
|
|
"M": formatUTCMinutes,
|
|
"p": formatUTCPeriod,
|
|
"q": formatUTCQuarter,
|
|
"Q": formatUnixTimestamp,
|
|
"s": formatUnixTimestampSeconds,
|
|
"S": formatUTCSeconds,
|
|
"u": formatUTCWeekdayNumberMonday,
|
|
"U": formatUTCWeekNumberSunday,
|
|
"V": formatUTCWeekNumberISO,
|
|
"w": formatUTCWeekdayNumberSunday,
|
|
"W": formatUTCWeekNumberMonday,
|
|
"x": null,
|
|
"X": null,
|
|
"y": formatUTCYear,
|
|
"Y": formatUTCFullYear,
|
|
"Z": formatUTCZone,
|
|
"%": formatLiteralPercent
|
|
};
|
|
var parses = {
|
|
"a": parseShortWeekday,
|
|
"A": parseWeekday,
|
|
"b": parseShortMonth,
|
|
"B": parseMonth,
|
|
"c": parseLocaleDateTime,
|
|
"d": parseDayOfMonth,
|
|
"e": parseDayOfMonth,
|
|
"f": parseMicroseconds,
|
|
"g": parseYear,
|
|
"G": parseFullYear,
|
|
"H": parseHour24,
|
|
"I": parseHour24,
|
|
"j": parseDayOfYear,
|
|
"L": parseMilliseconds,
|
|
"m": parseMonthNumber,
|
|
"M": parseMinutes,
|
|
"p": parsePeriod,
|
|
"q": parseQuarter,
|
|
"Q": parseUnixTimestamp,
|
|
"s": parseUnixTimestampSeconds,
|
|
"S": parseSeconds,
|
|
"u": parseWeekdayNumberMonday,
|
|
"U": parseWeekNumberSunday,
|
|
"V": parseWeekNumberISO,
|
|
"w": parseWeekdayNumberSunday,
|
|
"W": parseWeekNumberMonday,
|
|
"x": parseLocaleDate,
|
|
"X": parseLocaleTime,
|
|
"y": parseYear,
|
|
"Y": parseFullYear,
|
|
"Z": parseZone,
|
|
"%": parseLiteralPercent
|
|
};
|
|
formats.x = newFormat(locale_date, formats);
|
|
formats.X = newFormat(locale_time, formats);
|
|
formats.c = newFormat(locale_dateTime, formats);
|
|
utcFormats.x = newFormat(locale_date, utcFormats);
|
|
utcFormats.X = newFormat(locale_time, utcFormats);
|
|
utcFormats.c = newFormat(locale_dateTime, utcFormats);
|
|
function newFormat(specifier, formats2) {
|
|
return function(date) {
|
|
var string = [], i = -1, j = 0, n = specifier.length, c, pad2, format2;
|
|
if (!(date instanceof Date)) date = /* @__PURE__ */ new Date(+date);
|
|
while (++i < n) {
|
|
if (specifier.charCodeAt(i) === 37) {
|
|
string.push(specifier.slice(j, i));
|
|
if ((pad2 = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
|
|
else pad2 = c === "e" ? " " : "0";
|
|
if (format2 = formats2[c]) c = format2(date, pad2);
|
|
string.push(c);
|
|
j = i + 1;
|
|
}
|
|
}
|
|
string.push(specifier.slice(j, i));
|
|
return string.join("");
|
|
};
|
|
}
|
|
function newParse(specifier, Z) {
|
|
return function(string) {
|
|
var d = newDate(1900, void 0, 1), i = parseSpecifier(d, specifier, string += "", 0), week, day;
|
|
if (i != string.length) return null;
|
|
if ("Q" in d) return new Date(d.Q);
|
|
if ("s" in d) return new Date(d.s * 1e3 + ("L" in d ? d.L : 0));
|
|
if (Z && !("Z" in d)) d.Z = 0;
|
|
if ("p" in d) d.H = d.H % 12 + d.p * 12;
|
|
if (d.m === void 0) d.m = "q" in d ? d.q : 0;
|
|
if ("V" in d) {
|
|
if (d.V < 1 || d.V > 53) return null;
|
|
if (!("w" in d)) d.w = 1;
|
|
if ("Z" in d) {
|
|
week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay();
|
|
week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week);
|
|
week = utcDay.offset(week, (d.V - 1) * 7);
|
|
d.y = week.getUTCFullYear();
|
|
d.m = week.getUTCMonth();
|
|
d.d = week.getUTCDate() + (d.w + 6) % 7;
|
|
} else {
|
|
week = localDate(newDate(d.y, 0, 1)), day = week.getDay();
|
|
week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week);
|
|
week = timeDay.offset(week, (d.V - 1) * 7);
|
|
d.y = week.getFullYear();
|
|
d.m = week.getMonth();
|
|
d.d = week.getDate() + (d.w + 6) % 7;
|
|
}
|
|
} else if ("W" in d || "U" in d) {
|
|
if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
|
|
day = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();
|
|
d.m = 0;
|
|
d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;
|
|
}
|
|
if ("Z" in d) {
|
|
d.H += d.Z / 100 | 0;
|
|
d.M += d.Z % 100;
|
|
return utcDate(d);
|
|
}
|
|
return localDate(d);
|
|
};
|
|
}
|
|
function parseSpecifier(d, specifier, string, j) {
|
|
var i = 0, n = specifier.length, m = string.length, c, parse;
|
|
while (i < n) {
|
|
if (j >= m) return -1;
|
|
c = specifier.charCodeAt(i++);
|
|
if (c === 37) {
|
|
c = specifier.charAt(i++);
|
|
parse = parses[c in pads ? specifier.charAt(i++) : c];
|
|
if (!parse || (j = parse(d, string, j)) < 0) return -1;
|
|
} else if (c != string.charCodeAt(j++)) {
|
|
return -1;
|
|
}
|
|
}
|
|
return j;
|
|
}
|
|
function parsePeriod(d, string, i) {
|
|
var n = periodRe.exec(string.slice(i));
|
|
return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
|
|
}
|
|
function parseShortWeekday(d, string, i) {
|
|
var n = shortWeekdayRe.exec(string.slice(i));
|
|
return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
|
|
}
|
|
function parseWeekday(d, string, i) {
|
|
var n = weekdayRe.exec(string.slice(i));
|
|
return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
|
|
}
|
|
function parseShortMonth(d, string, i) {
|
|
var n = shortMonthRe.exec(string.slice(i));
|
|
return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
|
|
}
|
|
function parseMonth(d, string, i) {
|
|
var n = monthRe.exec(string.slice(i));
|
|
return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
|
|
}
|
|
function parseLocaleDateTime(d, string, i) {
|
|
return parseSpecifier(d, locale_dateTime, string, i);
|
|
}
|
|
function parseLocaleDate(d, string, i) {
|
|
return parseSpecifier(d, locale_date, string, i);
|
|
}
|
|
function parseLocaleTime(d, string, i) {
|
|
return parseSpecifier(d, locale_time, string, i);
|
|
}
|
|
function formatShortWeekday(d) {
|
|
return locale_shortWeekdays[d.getDay()];
|
|
}
|
|
function formatWeekday(d) {
|
|
return locale_weekdays[d.getDay()];
|
|
}
|
|
function formatShortMonth(d) {
|
|
return locale_shortMonths[d.getMonth()];
|
|
}
|
|
function formatMonth(d) {
|
|
return locale_months[d.getMonth()];
|
|
}
|
|
function formatPeriod(d) {
|
|
return locale_periods[+(d.getHours() >= 12)];
|
|
}
|
|
function formatQuarter(d) {
|
|
return 1 + ~~(d.getMonth() / 3);
|
|
}
|
|
function formatUTCShortWeekday(d) {
|
|
return locale_shortWeekdays[d.getUTCDay()];
|
|
}
|
|
function formatUTCWeekday(d) {
|
|
return locale_weekdays[d.getUTCDay()];
|
|
}
|
|
function formatUTCShortMonth(d) {
|
|
return locale_shortMonths[d.getUTCMonth()];
|
|
}
|
|
function formatUTCMonth(d) {
|
|
return locale_months[d.getUTCMonth()];
|
|
}
|
|
function formatUTCPeriod(d) {
|
|
return locale_periods[+(d.getUTCHours() >= 12)];
|
|
}
|
|
function formatUTCQuarter(d) {
|
|
return 1 + ~~(d.getUTCMonth() / 3);
|
|
}
|
|
return {
|
|
format: function(specifier) {
|
|
var f = newFormat(specifier += "", formats);
|
|
f.toString = function() {
|
|
return specifier;
|
|
};
|
|
return f;
|
|
},
|
|
parse: function(specifier) {
|
|
var p = newParse(specifier += "", false);
|
|
p.toString = function() {
|
|
return specifier;
|
|
};
|
|
return p;
|
|
},
|
|
utcFormat: function(specifier) {
|
|
var f = newFormat(specifier += "", utcFormats);
|
|
f.toString = function() {
|
|
return specifier;
|
|
};
|
|
return f;
|
|
},
|
|
utcParse: function(specifier) {
|
|
var p = newParse(specifier += "", true);
|
|
p.toString = function() {
|
|
return specifier;
|
|
};
|
|
return p;
|
|
}
|
|
};
|
|
}
|
|
var pads = { "-": "", "_": " ", "0": "0" };
|
|
var numberRe = /^\s*\d+/;
|
|
var percentRe = /^%/;
|
|
var requoteRe = /[\\^$*+?|[\]().{}]/g;
|
|
function pad(value, fill, width) {
|
|
var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length;
|
|
return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
|
|
}
|
|
function requote(s) {
|
|
return s.replace(requoteRe, "\\$&");
|
|
}
|
|
function formatRe(names) {
|
|
return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
|
|
}
|
|
function formatLookup(names) {
|
|
return new Map(names.map((name, i) => [name.toLowerCase(), i]));
|
|
}
|
|
function parseWeekdayNumberSunday(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 1));
|
|
return n ? (d.w = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseWeekdayNumberMonday(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 1));
|
|
return n ? (d.u = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseWeekNumberSunday(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.U = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseWeekNumberISO(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.V = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseWeekNumberMonday(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.W = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseFullYear(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 4));
|
|
return n ? (d.y = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseYear(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2e3), i + n[0].length) : -1;
|
|
}
|
|
function parseZone(d, string, i) {
|
|
var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
|
|
return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
|
|
}
|
|
function parseQuarter(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 1));
|
|
return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;
|
|
}
|
|
function parseMonthNumber(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
|
|
}
|
|
function parseDayOfMonth(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.d = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseDayOfYear(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 3));
|
|
return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseHour24(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.H = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseMinutes(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.M = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseSeconds(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 2));
|
|
return n ? (d.S = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseMilliseconds(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 3));
|
|
return n ? (d.L = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseMicroseconds(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i, i + 6));
|
|
return n ? (d.L = Math.floor(n[0] / 1e3), i + n[0].length) : -1;
|
|
}
|
|
function parseLiteralPercent(d, string, i) {
|
|
var n = percentRe.exec(string.slice(i, i + 1));
|
|
return n ? i + n[0].length : -1;
|
|
}
|
|
function parseUnixTimestamp(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i));
|
|
return n ? (d.Q = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function parseUnixTimestampSeconds(d, string, i) {
|
|
var n = numberRe.exec(string.slice(i));
|
|
return n ? (d.s = +n[0], i + n[0].length) : -1;
|
|
}
|
|
function formatDayOfMonth(d, p) {
|
|
return pad(d.getDate(), p, 2);
|
|
}
|
|
function formatHour24(d, p) {
|
|
return pad(d.getHours(), p, 2);
|
|
}
|
|
function formatHour12(d, p) {
|
|
return pad(d.getHours() % 12 || 12, p, 2);
|
|
}
|
|
function formatDayOfYear(d, p) {
|
|
return pad(1 + timeDay.count(timeYear(d), d), p, 3);
|
|
}
|
|
function formatMilliseconds(d, p) {
|
|
return pad(d.getMilliseconds(), p, 3);
|
|
}
|
|
function formatMicroseconds(d, p) {
|
|
return formatMilliseconds(d, p) + "000";
|
|
}
|
|
function formatMonthNumber(d, p) {
|
|
return pad(d.getMonth() + 1, p, 2);
|
|
}
|
|
function formatMinutes(d, p) {
|
|
return pad(d.getMinutes(), p, 2);
|
|
}
|
|
function formatSeconds(d, p) {
|
|
return pad(d.getSeconds(), p, 2);
|
|
}
|
|
function formatWeekdayNumberMonday(d) {
|
|
var day = d.getDay();
|
|
return day === 0 ? 7 : day;
|
|
}
|
|
function formatWeekNumberSunday(d, p) {
|
|
return pad(timeSunday.count(timeYear(d) - 1, d), p, 2);
|
|
}
|
|
function dISO(d) {
|
|
var day = d.getDay();
|
|
return day >= 4 || day === 0 ? timeThursday(d) : timeThursday.ceil(d);
|
|
}
|
|
function formatWeekNumberISO(d, p) {
|
|
d = dISO(d);
|
|
return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2);
|
|
}
|
|
function formatWeekdayNumberSunday(d) {
|
|
return d.getDay();
|
|
}
|
|
function formatWeekNumberMonday(d, p) {
|
|
return pad(timeMonday.count(timeYear(d) - 1, d), p, 2);
|
|
}
|
|
function formatYear(d, p) {
|
|
return pad(d.getFullYear() % 100, p, 2);
|
|
}
|
|
function formatYearISO(d, p) {
|
|
d = dISO(d);
|
|
return pad(d.getFullYear() % 100, p, 2);
|
|
}
|
|
function formatFullYear(d, p) {
|
|
return pad(d.getFullYear() % 1e4, p, 4);
|
|
}
|
|
function formatFullYearISO(d, p) {
|
|
var day = d.getDay();
|
|
d = day >= 4 || day === 0 ? timeThursday(d) : timeThursday.ceil(d);
|
|
return pad(d.getFullYear() % 1e4, p, 4);
|
|
}
|
|
function formatZone(d) {
|
|
var z = d.getTimezoneOffset();
|
|
return (z > 0 ? "-" : (z *= -1, "+")) + pad(z / 60 | 0, "0", 2) + pad(z % 60, "0", 2);
|
|
}
|
|
function formatUTCDayOfMonth(d, p) {
|
|
return pad(d.getUTCDate(), p, 2);
|
|
}
|
|
function formatUTCHour24(d, p) {
|
|
return pad(d.getUTCHours(), p, 2);
|
|
}
|
|
function formatUTCHour12(d, p) {
|
|
return pad(d.getUTCHours() % 12 || 12, p, 2);
|
|
}
|
|
function formatUTCDayOfYear(d, p) {
|
|
return pad(1 + utcDay.count(utcYear(d), d), p, 3);
|
|
}
|
|
function formatUTCMilliseconds(d, p) {
|
|
return pad(d.getUTCMilliseconds(), p, 3);
|
|
}
|
|
function formatUTCMicroseconds(d, p) {
|
|
return formatUTCMilliseconds(d, p) + "000";
|
|
}
|
|
function formatUTCMonthNumber(d, p) {
|
|
return pad(d.getUTCMonth() + 1, p, 2);
|
|
}
|
|
function formatUTCMinutes(d, p) {
|
|
return pad(d.getUTCMinutes(), p, 2);
|
|
}
|
|
function formatUTCSeconds(d, p) {
|
|
return pad(d.getUTCSeconds(), p, 2);
|
|
}
|
|
function formatUTCWeekdayNumberMonday(d) {
|
|
var dow = d.getUTCDay();
|
|
return dow === 0 ? 7 : dow;
|
|
}
|
|
function formatUTCWeekNumberSunday(d, p) {
|
|
return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);
|
|
}
|
|
function UTCdISO(d) {
|
|
var day = d.getUTCDay();
|
|
return day >= 4 || day === 0 ? utcThursday(d) : utcThursday.ceil(d);
|
|
}
|
|
function formatUTCWeekNumberISO(d, p) {
|
|
d = UTCdISO(d);
|
|
return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);
|
|
}
|
|
function formatUTCWeekdayNumberSunday(d) {
|
|
return d.getUTCDay();
|
|
}
|
|
function formatUTCWeekNumberMonday(d, p) {
|
|
return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);
|
|
}
|
|
function formatUTCYear(d, p) {
|
|
return pad(d.getUTCFullYear() % 100, p, 2);
|
|
}
|
|
function formatUTCYearISO(d, p) {
|
|
d = UTCdISO(d);
|
|
return pad(d.getUTCFullYear() % 100, p, 2);
|
|
}
|
|
function formatUTCFullYear(d, p) {
|
|
return pad(d.getUTCFullYear() % 1e4, p, 4);
|
|
}
|
|
function formatUTCFullYearISO(d, p) {
|
|
var day = d.getUTCDay();
|
|
d = day >= 4 || day === 0 ? utcThursday(d) : utcThursday.ceil(d);
|
|
return pad(d.getUTCFullYear() % 1e4, p, 4);
|
|
}
|
|
function formatUTCZone() {
|
|
return "+0000";
|
|
}
|
|
function formatLiteralPercent() {
|
|
return "%";
|
|
}
|
|
function formatUnixTimestamp(d) {
|
|
return +d;
|
|
}
|
|
function formatUnixTimestampSeconds(d) {
|
|
return Math.floor(+d / 1e3);
|
|
}
|
|
|
|
// node_modules/d3-time-format/src/defaultLocale.js
|
|
var locale2;
|
|
var timeFormat;
|
|
var timeParse;
|
|
var utcFormat;
|
|
var utcParse;
|
|
defaultLocale2({
|
|
dateTime: "%x, %X",
|
|
date: "%-m/%-d/%Y",
|
|
time: "%-I:%M:%S %p",
|
|
periods: ["AM", "PM"],
|
|
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
|
shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
|
shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
|
});
|
|
function defaultLocale2(definition) {
|
|
locale2 = formatLocale(definition);
|
|
timeFormat = locale2.format;
|
|
timeParse = locale2.parse;
|
|
utcFormat = locale2.utcFormat;
|
|
utcParse = locale2.utcParse;
|
|
return locale2;
|
|
}
|
|
|
|
// assets/src/heatmap.ts
|
|
var DEFAULT_CONFIG = {
|
|
cellSize: 13,
|
|
cellGap: 2,
|
|
marginTop: 20,
|
|
marginLeft: 30,
|
|
marginBottom: 4
|
|
};
|
|
var FALLBACK_COLORS = ["#9be9a8", "#40c463", "#30a14e", "#216e39"];
|
|
var DAY_LABELS = ["Mon", "", "Wed", "", "Fri", "", ""];
|
|
var MONTH_FORMAT = timeFormat("%b");
|
|
var DATE_FORMAT = timeFormat("%Y-%m-%d");
|
|
var DISPLAY_FORMAT = timeFormat("%a, %b %-d, %Y");
|
|
function resolveColors(container) {
|
|
try {
|
|
const style = getComputedStyle(container);
|
|
const test = style.getPropertyValue("--tblr-bg-surface");
|
|
if (!test) return FALLBACK_COLORS;
|
|
return FALLBACK_COLORS;
|
|
} catch {
|
|
return FALLBACK_COLORS;
|
|
}
|
|
}
|
|
function buildDateMap(days) {
|
|
const map2 = /* @__PURE__ */ new Map();
|
|
for (const d of days) {
|
|
map2.set(d.date, d);
|
|
}
|
|
return map2;
|
|
}
|
|
function generateCells(begin, end, dateMap) {
|
|
const firstMonday = timeMonday.floor(begin);
|
|
const cells = [];
|
|
let current = new Date(begin);
|
|
while (current <= end) {
|
|
const dateStr = DATE_FORMAT(current);
|
|
const weeksSinceStart = timeMonday.count(firstMonday, current);
|
|
const dayOfWeek = (current.getDay() + 6) % 7;
|
|
cells.push({
|
|
date: new Date(current),
|
|
dateStr,
|
|
entry: dateMap.get(dateStr) || null,
|
|
week: weeksSinceStart,
|
|
day: dayOfWeek
|
|
});
|
|
current = timeDay.offset(current, 1);
|
|
}
|
|
return cells;
|
|
}
|
|
function createTooltip() {
|
|
const tip = document.createElement("div");
|
|
tip.className = "heatmap-tooltip";
|
|
tip.style.display = "none";
|
|
return tip;
|
|
}
|
|
function renderHeatmap(container, data, config = DEFAULT_CONFIG, onCellClick, emptyMessage) {
|
|
container.innerHTML = "";
|
|
if (!data.days || data.days.length === 0) {
|
|
const msg = document.createElement("div");
|
|
msg.textContent = emptyMessage || "No tracking data available";
|
|
msg.style.padding = "1rem";
|
|
msg.style.color = "var(--tblr-secondary, #6c757d)";
|
|
container.appendChild(msg);
|
|
return;
|
|
}
|
|
const dateMap = buildDateMap(data.days);
|
|
const begin = new Date(data.range.begin);
|
|
const end = new Date(data.range.end);
|
|
const cells = generateCells(begin, end, dateMap);
|
|
const maxHours = max(data.days, (d) => d.hours) || 1;
|
|
const colors = resolveColors(container);
|
|
const colorScale = quantize().domain([0, maxHours]).range(colors);
|
|
const { cellGap, marginTop, marginLeft, marginBottom } = config;
|
|
const numWeeks = (max(cells, (c) => c.week) ?? 0) + 1;
|
|
const containerWidth = container.clientWidth || 800;
|
|
const maxCellSize = 18;
|
|
const cellSize = Math.min(maxCellSize, Math.max(2, Math.floor((containerWidth - marginLeft) / numWeeks) - cellGap));
|
|
const step = cellSize + cellGap;
|
|
const svgWidth = marginLeft + numWeeks * step;
|
|
const svgHeight = marginTop + 7 * step + marginBottom;
|
|
const wrapper = document.createElement("div");
|
|
wrapper.style.maxWidth = `${svgWidth}px`;
|
|
wrapper.style.margin = "0 auto";
|
|
container.appendChild(wrapper);
|
|
const svg = select_default2(wrapper).append("svg").attr("width", svgWidth).attr("height", svgHeight).attr("class", "heatmap-svg");
|
|
const months = [];
|
|
const firstMonday = timeMonday.floor(begin);
|
|
timeMonth.range(timeMonth.ceil(begin), end).forEach((m) => {
|
|
months.push({
|
|
date: m,
|
|
week: timeMonday.count(firstMonday, m)
|
|
});
|
|
});
|
|
svg.selectAll(".month-label").data(months).join("text").attr("class", "heatmap-label month-label").attr("x", (d) => marginLeft + d.week * step).attr("y", marginTop - 6).text((d) => MONTH_FORMAT(d.date));
|
|
svg.selectAll(".day-label").data(DAY_LABELS).join("text").attr("class", "heatmap-label day-label").attr("x", marginLeft - 6).attr("y", (_d, i) => marginTop + i * step + cellSize - 2).attr("text-anchor", "end").text((d) => d);
|
|
const tooltip = createTooltip();
|
|
wrapper.style.position = "relative";
|
|
wrapper.appendChild(tooltip);
|
|
svg.selectAll(".heatmap-cell").data(cells).join("rect").attr(
|
|
"class",
|
|
(d) => d.entry ? "heatmap-cell" : "heatmap-cell heatmap-empty"
|
|
).attr("x", (d) => marginLeft + d.week * step).attr("y", (d) => marginTop + d.day * step).attr("width", cellSize).attr("height", cellSize).attr("fill", (d) => d.entry ? colorScale(d.entry.hours) : "").on("mouseenter", function(event, d) {
|
|
const hours = d.entry ? d.entry.hours.toFixed(1) : "0.0";
|
|
const count = d.entry ? d.entry.count : 0;
|
|
tooltip.innerHTML = `<strong>${DISPLAY_FORMAT(d.date)}</strong><br>${hours}h (${count} entries)`;
|
|
tooltip.style.display = "block";
|
|
const rect = event.target.getBoundingClientRect();
|
|
const wrapperRect = wrapper.getBoundingClientRect();
|
|
tooltip.style.left = `${rect.left - wrapperRect.left + cellSize / 2}px`;
|
|
tooltip.style.top = `${rect.top - wrapperRect.top - 40}px`;
|
|
}).on("mouseleave", function() {
|
|
tooltip.style.display = "none";
|
|
}).on("click", function(_event, d) {
|
|
if (!onCellClick) return;
|
|
onCellClick(d.dateStr);
|
|
});
|
|
}
|
|
function init(container) {
|
|
const baseUrl = container.getAttribute("data-url");
|
|
if (!baseUrl) {
|
|
console.error("KimaiHeatmap: missing data-url attribute");
|
|
return;
|
|
}
|
|
const timesheetUrl = container.getAttribute("data-timesheet-url") || "/en/timesheet/";
|
|
const projectsJson = container.getAttribute("data-projects");
|
|
const projects = projectsJson ? JSON.parse(projectsJson) : [];
|
|
let activeProjectId = null;
|
|
const onCellClick = (dateStr) => {
|
|
const daterange = `${dateStr} - ${dateStr}`;
|
|
let url = `${timesheetUrl}?daterange=${encodeURIComponent(daterange)}`;
|
|
if (activeProjectId) {
|
|
url += `&projects[]=${activeProjectId}`;
|
|
}
|
|
window.location.href = url;
|
|
};
|
|
container.innerHTML = "";
|
|
const wrapper = document.createElement("div");
|
|
wrapper.className = "heatmap-wrapper";
|
|
const svgArea = document.createElement("div");
|
|
svgArea.className = "heatmap-svg-area";
|
|
wrapper.appendChild(svgArea);
|
|
if (projects.length > 0) {
|
|
const filterDiv = document.createElement("div");
|
|
filterDiv.className = "heatmap-filter";
|
|
const select = document.createElement("select");
|
|
select.className = "form-select form-select-sm";
|
|
select.setAttribute("aria-label", "Filter by project");
|
|
const defaultOpt = document.createElement("option");
|
|
defaultOpt.value = "";
|
|
defaultOpt.textContent = "All Projects";
|
|
select.appendChild(defaultOpt);
|
|
for (const p of projects) {
|
|
const opt = document.createElement("option");
|
|
opt.value = String(p.id);
|
|
opt.textContent = p.name;
|
|
select.appendChild(opt);
|
|
}
|
|
select.addEventListener("change", () => {
|
|
const val = select.value;
|
|
activeProjectId = val ? parseInt(val, 10) : null;
|
|
const fetchUrl = val ? `${baseUrl}?project=${val}` : baseUrl;
|
|
fetch(fetchUrl).then((res) => {
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
return res.json();
|
|
}).then((data) => {
|
|
renderHeatmap(svgArea, data, DEFAULT_CONFIG, onCellClick, "No tracking data for this project");
|
|
}).catch((err) => {
|
|
console.error("KimaiHeatmap: failed to load filtered data", err);
|
|
});
|
|
});
|
|
filterDiv.appendChild(select);
|
|
wrapper.appendChild(filterDiv);
|
|
}
|
|
container.appendChild(wrapper);
|
|
fetch(baseUrl).then((res) => {
|
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
return res.json();
|
|
}).then((data) => {
|
|
renderHeatmap(svgArea, data, DEFAULT_CONFIG, onCellClick);
|
|
}).catch((err) => {
|
|
console.error("KimaiHeatmap: failed to load data", err);
|
|
svgArea.textContent = "Failed to load heatmap data";
|
|
});
|
|
}
|
|
return __toCommonJS(heatmap_exports);
|
|
})();
|