@trops/dash-core 0.1.150 → 0.1.152
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +363 -48
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +363 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2713,9 +2713,9 @@ var LayoutContainer = function LayoutContainer(_ref) {
|
|
|
2713
2713
|
|
|
2714
2714
|
function ownKeys$A(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
2715
2715
|
function _objectSpread$A(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$A(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$A(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
2716
|
-
function _createForOfIteratorHelper$
|
|
2717
|
-
function _unsupportedIterableToArray$
|
|
2718
|
-
function _arrayLikeToArray$
|
|
2716
|
+
function _createForOfIteratorHelper$e(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$e(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
2717
|
+
function _unsupportedIterableToArray$e(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$e(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$e(r, a) : void 0; } }
|
|
2718
|
+
function _arrayLikeToArray$e(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; }
|
|
2719
2719
|
/**
|
|
2720
2720
|
* Layout template definitions for the dashboard template picker.
|
|
2721
2721
|
*
|
|
@@ -2951,7 +2951,7 @@ function createLayoutFromTemplate(template) {
|
|
|
2951
2951
|
cols: template.cols,
|
|
2952
2952
|
gap: "gap-2"
|
|
2953
2953
|
};
|
|
2954
|
-
var _iterator = _createForOfIteratorHelper$
|
|
2954
|
+
var _iterator = _createForOfIteratorHelper$e(template.cells),
|
|
2955
2955
|
_step;
|
|
2956
2956
|
try {
|
|
2957
2957
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -9794,9 +9794,9 @@ var PanelEditItem = function PanelEditItem(_ref) {
|
|
|
9794
9794
|
};
|
|
9795
9795
|
|
|
9796
9796
|
var _excluded$5 = ["rows", "cols"];
|
|
9797
|
-
function _createForOfIteratorHelper$
|
|
9798
|
-
function _unsupportedIterableToArray$
|
|
9799
|
-
function _arrayLikeToArray$
|
|
9797
|
+
function _createForOfIteratorHelper$d(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$d(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
9798
|
+
function _unsupportedIterableToArray$d(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$d(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$d(r, a) : void 0; } }
|
|
9799
|
+
function _arrayLikeToArray$d(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; }
|
|
9800
9800
|
function ownKeys$x(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
9801
9801
|
function _objectSpread$x(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$x(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$x(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
9802
9802
|
var defaultGrid = {
|
|
@@ -9949,7 +9949,7 @@ function GridEditor(_ref) {
|
|
|
9949
9949
|
function sortObjectByKeys(obj) {
|
|
9950
9950
|
var sortedKeys = Object.keys(obj).sort();
|
|
9951
9951
|
var sortedObj = {};
|
|
9952
|
-
var _iterator = _createForOfIteratorHelper$
|
|
9952
|
+
var _iterator = _createForOfIteratorHelper$d(sortedKeys),
|
|
9953
9953
|
_step;
|
|
9954
9954
|
try {
|
|
9955
9955
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -10422,9 +10422,9 @@ var PanelEditItemNotifications = function PanelEditItemNotifications(_ref) {
|
|
|
10422
10422
|
});
|
|
10423
10423
|
};
|
|
10424
10424
|
|
|
10425
|
-
function _createForOfIteratorHelper$
|
|
10426
|
-
function _unsupportedIterableToArray$
|
|
10427
|
-
function _arrayLikeToArray$
|
|
10425
|
+
function _createForOfIteratorHelper$c(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$c(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
10426
|
+
function _unsupportedIterableToArray$c(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$c(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$c(r, a) : void 0; } }
|
|
10427
|
+
function _arrayLikeToArray$c(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; }
|
|
10428
10428
|
function ownKeys$v(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
10429
10429
|
function _objectSpread$v(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$v(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$v(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
10430
10430
|
var DAYS = [{
|
|
@@ -10743,12 +10743,17 @@ var PanelEditItemSchedule = function PanelEditItemSchedule(_ref2) {
|
|
|
10743
10743
|
_useState12 = _slicedToArray(_useState11, 2),
|
|
10744
10744
|
taskStates = _useState12[0],
|
|
10745
10745
|
setTaskStates = _useState12[1];
|
|
10746
|
+
var _useState13 = React.useState(true),
|
|
10747
|
+
_useState14 = _slicedToArray(_useState13, 2),
|
|
10748
|
+
isLoading = _useState14[0],
|
|
10749
|
+
setIsLoading = _useState14[1];
|
|
10746
10750
|
React.useEffect(function () {
|
|
10747
10751
|
var _window$mainApi4;
|
|
10748
10752
|
if (scheduledTaskDefs.length > 0 && widgetUuid && (_window$mainApi4 = window.mainApi) !== null && _window$mainApi4 !== void 0 && (_window$mainApi4 = _window$mainApi4.scheduler) !== null && _window$mainApi4 !== void 0 && _window$mainApi4.getTasks) {
|
|
10753
|
+
setIsLoading(true);
|
|
10749
10754
|
window.mainApi.scheduler.getTasks(widgetUuid).then(function (tasks) {
|
|
10750
10755
|
var stateMap = {};
|
|
10751
|
-
var _iterator = _createForOfIteratorHelper$
|
|
10756
|
+
var _iterator = _createForOfIteratorHelper$c(tasks || []),
|
|
10752
10757
|
_step;
|
|
10753
10758
|
try {
|
|
10754
10759
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -10761,10 +10766,25 @@ var PanelEditItemSchedule = function PanelEditItemSchedule(_ref2) {
|
|
|
10761
10766
|
_iterator.f();
|
|
10762
10767
|
}
|
|
10763
10768
|
setTaskStates(stateMap);
|
|
10769
|
+
setIsLoading(false);
|
|
10764
10770
|
});
|
|
10771
|
+
} else {
|
|
10772
|
+
setIsLoading(false);
|
|
10765
10773
|
}
|
|
10766
10774
|
}, [widgetUuid, scheduledTaskDefs.length]);
|
|
10767
10775
|
if (!item || scheduledTaskDefs.length === 0) return null;
|
|
10776
|
+
if (isLoading) {
|
|
10777
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
10778
|
+
className: "flex flex-col flex-1 min-h-0 p-6",
|
|
10779
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
|
|
10780
|
+
title: "Schedule",
|
|
10781
|
+
padding: false
|
|
10782
|
+
}), /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
10783
|
+
className: "text-sm opacity-50 mt-4",
|
|
10784
|
+
children: "Loading schedules..."
|
|
10785
|
+
})]
|
|
10786
|
+
});
|
|
10787
|
+
}
|
|
10768
10788
|
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
10769
10789
|
className: "flex flex-col flex-1 min-h-0 overflow-y-auto p-6 space-y-4",
|
|
10770
10790
|
children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
|
|
@@ -13583,9 +13603,9 @@ var getUserConfigurableProviders = function getUserConfigurableProviders(provide
|
|
|
13583
13603
|
});
|
|
13584
13604
|
};
|
|
13585
13605
|
|
|
13586
|
-
function _createForOfIteratorHelper$
|
|
13587
|
-
function _unsupportedIterableToArray$
|
|
13588
|
-
function _arrayLikeToArray$
|
|
13606
|
+
function _createForOfIteratorHelper$b(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$b(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
13607
|
+
function _unsupportedIterableToArray$b(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$b(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$b(r, a) : void 0; } }
|
|
13608
|
+
function _arrayLikeToArray$b(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; }
|
|
13589
13609
|
function ownKeys$s(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
13590
13610
|
function _objectSpread$s(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$s(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$s(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13591
13611
|
var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
|
|
@@ -13852,11 +13872,11 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
|
|
|
13852
13872
|
|
|
13853
13873
|
// Flatten all widgets from all packages for the widget list
|
|
13854
13874
|
flatWidgets = [];
|
|
13855
|
-
_iterator = _createForOfIteratorHelper$
|
|
13875
|
+
_iterator = _createForOfIteratorHelper$b(result.packages || []);
|
|
13856
13876
|
try {
|
|
13857
13877
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
13858
13878
|
pkg = _step.value;
|
|
13859
|
-
_iterator2 = _createForOfIteratorHelper$
|
|
13879
|
+
_iterator2 = _createForOfIteratorHelper$b(pkg.widgets || []);
|
|
13860
13880
|
try {
|
|
13861
13881
|
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
13862
13882
|
widget = _step2.value;
|
|
@@ -15412,9 +15432,9 @@ var ProviderBadge = function ProviderBadge(_ref) {
|
|
|
15412
15432
|
});
|
|
15413
15433
|
};
|
|
15414
15434
|
|
|
15415
|
-
function _createForOfIteratorHelper$
|
|
15416
|
-
function _unsupportedIterableToArray$
|
|
15417
|
-
function _arrayLikeToArray$
|
|
15435
|
+
function _createForOfIteratorHelper$a(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$a(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
15436
|
+
function _unsupportedIterableToArray$a(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$a(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$a(r, a) : void 0; } }
|
|
15437
|
+
function _arrayLikeToArray$a(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; }
|
|
15418
15438
|
var WidgetCardHeader = function WidgetCardHeader(_ref) {
|
|
15419
15439
|
var item = _ref.item,
|
|
15420
15440
|
widget = _ref.widget,
|
|
@@ -15458,7 +15478,7 @@ var WidgetCardHeader = function WidgetCardHeader(_ref) {
|
|
|
15458
15478
|
var el = headerRef.current;
|
|
15459
15479
|
if (!el) return;
|
|
15460
15480
|
var observer = new ResizeObserver(function (entries) {
|
|
15461
|
-
var _iterator = _createForOfIteratorHelper$
|
|
15481
|
+
var _iterator = _createForOfIteratorHelper$a(entries),
|
|
15462
15482
|
_step;
|
|
15463
15483
|
try {
|
|
15464
15484
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
@@ -15759,6 +15779,286 @@ var WidgetCardHeader = function WidgetCardHeader(_ref) {
|
|
|
15759
15779
|
});
|
|
15760
15780
|
};
|
|
15761
15781
|
|
|
15782
|
+
/**
|
|
15783
|
+
* useWidgetSchedulerStatus
|
|
15784
|
+
*
|
|
15785
|
+
* Display-only hook for reading scheduler task state outside WidgetContext.
|
|
15786
|
+
* Used by WidgetCardStatusBar to show live timer status in the widget footer.
|
|
15787
|
+
*
|
|
15788
|
+
* Unlike useScheduler, this hook:
|
|
15789
|
+
* - Does NOT require WidgetContext (works outside the widget tree)
|
|
15790
|
+
* - Does NOT execute handlers — purely for display
|
|
15791
|
+
* - Calls mainApi.scheduler.getTasks() directly
|
|
15792
|
+
*
|
|
15793
|
+
* @param {string} widgetId - The widget instance UUID
|
|
15794
|
+
* @returns {{ tasks: Array, isLoading: boolean }}
|
|
15795
|
+
*/
|
|
15796
|
+
var useWidgetSchedulerStatus = function useWidgetSchedulerStatus(widgetId) {
|
|
15797
|
+
var _useState = React.useState([]),
|
|
15798
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
15799
|
+
tasks = _useState2[0],
|
|
15800
|
+
setTasks = _useState2[1];
|
|
15801
|
+
var _useState3 = React.useState(true),
|
|
15802
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
15803
|
+
isLoading = _useState4[0],
|
|
15804
|
+
setIsLoading = _useState4[1];
|
|
15805
|
+
var fetchTasks = React.useCallback(function () {
|
|
15806
|
+
var _window$mainApi;
|
|
15807
|
+
if (!widgetId || !((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && _window$mainApi.scheduler)) {
|
|
15808
|
+
setIsLoading(false);
|
|
15809
|
+
return;
|
|
15810
|
+
}
|
|
15811
|
+
window.mainApi.scheduler.getTasks(widgetId).then(function (result) {
|
|
15812
|
+
setTasks(result || []);
|
|
15813
|
+
setIsLoading(false);
|
|
15814
|
+
});
|
|
15815
|
+
}, [widgetId]);
|
|
15816
|
+
|
|
15817
|
+
// Load tasks on mount
|
|
15818
|
+
React.useEffect(function () {
|
|
15819
|
+
fetchTasks();
|
|
15820
|
+
}, [fetchTasks]);
|
|
15821
|
+
|
|
15822
|
+
// Subscribe to task-fired events to auto-refresh
|
|
15823
|
+
React.useEffect(function () {
|
|
15824
|
+
var _window$mainApi2;
|
|
15825
|
+
if (!widgetId || !((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && (_window$mainApi2 = _window$mainApi2.scheduler) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.onTaskFired)) return;
|
|
15826
|
+
var removeListener = window.mainApi.scheduler.onTaskFired(function (data) {
|
|
15827
|
+
if (data.widgetId !== widgetId) return;
|
|
15828
|
+
fetchTasks();
|
|
15829
|
+
});
|
|
15830
|
+
return removeListener;
|
|
15831
|
+
}, [widgetId, fetchTasks]);
|
|
15832
|
+
return {
|
|
15833
|
+
tasks: tasks,
|
|
15834
|
+
isLoading: isLoading
|
|
15835
|
+
};
|
|
15836
|
+
};
|
|
15837
|
+
|
|
15838
|
+
function _createForOfIteratorHelper$9(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray$9(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
15839
|
+
function _unsupportedIterableToArray$9(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray$9(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$9(r, a) : void 0; } }
|
|
15840
|
+
function _arrayLikeToArray$9(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; }
|
|
15841
|
+
function formatCountdown(ms) {
|
|
15842
|
+
if (ms == null || ms < 0) return "--";
|
|
15843
|
+
if (ms < 1000) return "< 1s";
|
|
15844
|
+
var totalSeconds = Math.floor(ms / 1000);
|
|
15845
|
+
var hours = Math.floor(totalSeconds / 3600);
|
|
15846
|
+
var minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
15847
|
+
var seconds = totalSeconds % 60;
|
|
15848
|
+
if (hours > 0) return "".concat(hours, "h ").concat(minutes, "m");
|
|
15849
|
+
if (minutes > 0) return "".concat(minutes, "m ").concat(seconds, "s");
|
|
15850
|
+
return "".concat(seconds, "s");
|
|
15851
|
+
}
|
|
15852
|
+
|
|
15853
|
+
/**
|
|
15854
|
+
* Format a timestamp as relative time ago.
|
|
15855
|
+
* @param {number|string} timestamp - epoch ms or ISO string
|
|
15856
|
+
* @returns {string} e.g. "2m ago", "1h ago", "just now"
|
|
15857
|
+
*/
|
|
15858
|
+
function formatRelativeTime(timestamp) {
|
|
15859
|
+
if (!timestamp) return null;
|
|
15860
|
+
var ts = typeof timestamp === "string" ? new Date(timestamp).getTime() : timestamp;
|
|
15861
|
+
var diff = Date.now() - ts;
|
|
15862
|
+
if (diff < 60000) return "just now";
|
|
15863
|
+
if (diff < 3600000) return "".concat(Math.floor(diff / 60000), "m ago");
|
|
15864
|
+
if (diff < 86400000) return "".concat(Math.floor(diff / 3600000), "h ago");
|
|
15865
|
+
return "".concat(Math.floor(diff / 86400000), "d ago");
|
|
15866
|
+
}
|
|
15867
|
+
|
|
15868
|
+
/**
|
|
15869
|
+
* Format a task's schedule as a human-readable description.
|
|
15870
|
+
* @param {Object} task - scheduler task object
|
|
15871
|
+
* @returns {string} e.g. "Every 5 min", "Mon, Wed at 09:00"
|
|
15872
|
+
*/
|
|
15873
|
+
function formatScheduleDescription(task) {
|
|
15874
|
+
if (task.scheduleType === "interval" && task.intervalMs) {
|
|
15875
|
+
var totalSeconds = Math.floor(task.intervalMs / 1000);
|
|
15876
|
+
if (totalSeconds < 60) return "Every ".concat(totalSeconds, "s");
|
|
15877
|
+
var minutes = Math.floor(totalSeconds / 60);
|
|
15878
|
+
if (minutes < 60) return "Every ".concat(minutes, " min");
|
|
15879
|
+
var hours = Math.floor(minutes / 60);
|
|
15880
|
+
var remainingMin = minutes % 60;
|
|
15881
|
+
if (remainingMin === 0) return "Every ".concat(hours, " hr");
|
|
15882
|
+
return "Every ".concat(hours, "h ").concat(remainingMin, "m");
|
|
15883
|
+
}
|
|
15884
|
+
if (task.scheduleType === "dayTime") {
|
|
15885
|
+
var dayMap = {
|
|
15886
|
+
mon: "Mon",
|
|
15887
|
+
tue: "Tue",
|
|
15888
|
+
wed: "Wed",
|
|
15889
|
+
thu: "Thu",
|
|
15890
|
+
fri: "Fri",
|
|
15891
|
+
sat: "Sat",
|
|
15892
|
+
sun: "Sun"
|
|
15893
|
+
};
|
|
15894
|
+
var days = (task.days || []).map(function (d) {
|
|
15895
|
+
return dayMap[d] || d;
|
|
15896
|
+
});
|
|
15897
|
+
var time = task.time || "00:00";
|
|
15898
|
+
if (days.length === 7) return "Daily at ".concat(time);
|
|
15899
|
+
if (days.length === 5 && ["mon", "tue", "wed", "thu", "fri"].every(function (d) {
|
|
15900
|
+
return (task.days || []).includes(d);
|
|
15901
|
+
})) {
|
|
15902
|
+
return "Mon\u2013Fri at ".concat(time);
|
|
15903
|
+
}
|
|
15904
|
+
return "".concat(days.join(", "), " at ").concat(time);
|
|
15905
|
+
}
|
|
15906
|
+
return "Scheduled";
|
|
15907
|
+
}
|
|
15908
|
+
|
|
15909
|
+
// ── Component ───────────────────────────────────────────────────────
|
|
15910
|
+
|
|
15911
|
+
var WidgetCardStatusBar = function WidgetCardStatusBar(_ref) {
|
|
15912
|
+
var item = _ref.item,
|
|
15913
|
+
_ref$className = _ref.className,
|
|
15914
|
+
className = _ref$className === void 0 ? "" : _ref$className;
|
|
15915
|
+
var _useState = React.useState(false),
|
|
15916
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
15917
|
+
expanded = _useState2[0],
|
|
15918
|
+
setExpanded = _useState2[1];
|
|
15919
|
+
var _useState3 = React.useState(Date.now()),
|
|
15920
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
15921
|
+
now = _useState4[0],
|
|
15922
|
+
setNow = _useState4[1];
|
|
15923
|
+
|
|
15924
|
+
// Check if widget declares scheduledTasks in its config
|
|
15925
|
+
var widgetConfig = item !== null && item !== void 0 && item.component ? ComponentManager.config(item.component, item) : null;
|
|
15926
|
+
var declaredTasks = (widgetConfig === null || widgetConfig === void 0 ? void 0 : widgetConfig.scheduledTasks) || [];
|
|
15927
|
+
|
|
15928
|
+
// Fetch live task state from the scheduler
|
|
15929
|
+
var _useWidgetSchedulerSt = useWidgetSchedulerStatus(item === null || item === void 0 ? void 0 : item.uuid),
|
|
15930
|
+
tasks = _useWidgetSchedulerSt.tasks,
|
|
15931
|
+
isLoading = _useWidgetSchedulerSt.isLoading;
|
|
15932
|
+
|
|
15933
|
+
// Tick every second for live countdowns
|
|
15934
|
+
React.useEffect(function () {
|
|
15935
|
+
if (tasks.length === 0) return;
|
|
15936
|
+
var interval = setInterval(function () {
|
|
15937
|
+
return setNow(Date.now());
|
|
15938
|
+
}, 1000);
|
|
15939
|
+
return function () {
|
|
15940
|
+
return clearInterval(interval);
|
|
15941
|
+
};
|
|
15942
|
+
}, [tasks.length]);
|
|
15943
|
+
|
|
15944
|
+
// Don't render if widget doesn't declare scheduled tasks or none are configured
|
|
15945
|
+
if (declaredTasks.length === 0) return null;
|
|
15946
|
+
if (isLoading) return null;
|
|
15947
|
+
if (tasks.length === 0) return null;
|
|
15948
|
+
var enabledTasks = tasks.filter(function (t) {
|
|
15949
|
+
return t.enabled;
|
|
15950
|
+
});
|
|
15951
|
+
var allPaused = enabledTasks.length === 0;
|
|
15952
|
+
|
|
15953
|
+
// Find soonest countdown among enabled tasks
|
|
15954
|
+
var soonestMs = null;
|
|
15955
|
+
var _iterator = _createForOfIteratorHelper$9(enabledTasks),
|
|
15956
|
+
_step;
|
|
15957
|
+
try {
|
|
15958
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
15959
|
+
var _task = _step.value;
|
|
15960
|
+
if (_task.nextFireAt) {
|
|
15961
|
+
var remaining = _task.nextFireAt - now;
|
|
15962
|
+
if (soonestMs === null || remaining < soonestMs) {
|
|
15963
|
+
soonestMs = remaining;
|
|
15964
|
+
}
|
|
15965
|
+
}
|
|
15966
|
+
}
|
|
15967
|
+
|
|
15968
|
+
// Collapsed summary text
|
|
15969
|
+
} catch (err) {
|
|
15970
|
+
_iterator.e(err);
|
|
15971
|
+
} finally {
|
|
15972
|
+
_iterator.f();
|
|
15973
|
+
}
|
|
15974
|
+
var summaryText;
|
|
15975
|
+
if (allPaused) {
|
|
15976
|
+
summaryText = "".concat(tasks.length, " timer").concat(tasks.length > 1 ? "s" : "", " (paused)");
|
|
15977
|
+
} else if (tasks.length === 1) {
|
|
15978
|
+
var task = tasks[0];
|
|
15979
|
+
var label = task.displayName || task.taskKey;
|
|
15980
|
+
if (task.enabled && soonestMs != null) {
|
|
15981
|
+
summaryText = "".concat(label, " \xB7 ").concat(formatCountdown(soonestMs));
|
|
15982
|
+
} else {
|
|
15983
|
+
summaryText = "".concat(label, " (paused)");
|
|
15984
|
+
}
|
|
15985
|
+
} else {
|
|
15986
|
+
summaryText = "".concat(tasks.length, " timers \xB7 next in ").concat(formatCountdown(soonestMs));
|
|
15987
|
+
}
|
|
15988
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
15989
|
+
className: "border-t border-gray-700/50 bg-gray-900/30 select-none ".concat(className),
|
|
15990
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("button", {
|
|
15991
|
+
type: "button",
|
|
15992
|
+
onClick: function onClick() {
|
|
15993
|
+
return setExpanded(!expanded);
|
|
15994
|
+
},
|
|
15995
|
+
className: "flex items-center w-full px-3 py-1 text-xs gap-2 cursor-pointer transition-colors hover:bg-gray-800/40 ".concat(allPaused ? "text-gray-500" : "text-blue-400"),
|
|
15996
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
|
|
15997
|
+
icon: "clock",
|
|
15998
|
+
className: "text-[10px] shrink-0"
|
|
15999
|
+
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
16000
|
+
className: "truncate flex-1 text-left",
|
|
16001
|
+
children: summaryText
|
|
16002
|
+
}), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
|
|
16003
|
+
icon: expanded ? "chevron-up" : "chevron-down",
|
|
16004
|
+
className: "text-[10px] text-gray-500 shrink-0"
|
|
16005
|
+
})]
|
|
16006
|
+
}), expanded && /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
16007
|
+
className: "px-3 pb-2 pt-1 space-y-2",
|
|
16008
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
16009
|
+
className: "text-[10px] font-semibold text-gray-400 uppercase tracking-wider",
|
|
16010
|
+
children: "Scheduled Tasks"
|
|
16011
|
+
}), tasks.map(function (task) {
|
|
16012
|
+
var remaining = task.enabled && task.nextFireAt ? task.nextFireAt - now : null;
|
|
16013
|
+
var lastFiredText = formatRelativeTime(task.lastFiredAt);
|
|
16014
|
+
return /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
16015
|
+
className: "flex flex-col gap-0.5",
|
|
16016
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
16017
|
+
className: "flex items-center justify-between text-xs",
|
|
16018
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
16019
|
+
className: "flex items-center gap-1.5",
|
|
16020
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
16021
|
+
className: "inline-block w-1.5 h-1.5 rounded-full ".concat(task.enabled ? "bg-green-500" : "bg-gray-600")
|
|
16022
|
+
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
16023
|
+
className: task.enabled ? "text-gray-200" : "text-gray-500",
|
|
16024
|
+
children: task.displayName || task.taskKey
|
|
16025
|
+
}), !task.enabled && /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
16026
|
+
className: "text-gray-600 text-[10px]",
|
|
16027
|
+
children: "(paused)"
|
|
16028
|
+
})]
|
|
16029
|
+
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
16030
|
+
className: "text-gray-500 text-[10px]",
|
|
16031
|
+
children: formatScheduleDescription(task)
|
|
16032
|
+
})]
|
|
16033
|
+
}), task.enabled && /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
16034
|
+
className: "text-[10px] text-gray-500 pl-4 flex items-center gap-1.5",
|
|
16035
|
+
children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
16036
|
+
children: ["Next in ", formatCountdown(remaining)]
|
|
16037
|
+
}), lastFiredText && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
16038
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
16039
|
+
className: "text-gray-700",
|
|
16040
|
+
children: "\xB7"
|
|
16041
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
16042
|
+
children: ["Last: ", lastFiredText]
|
|
16043
|
+
})]
|
|
16044
|
+
}), task.fireCount > 0 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
16045
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("span", {
|
|
16046
|
+
className: "text-gray-700",
|
|
16047
|
+
children: "\xB7"
|
|
16048
|
+
}), /*#__PURE__*/jsxRuntime.jsxs("span", {
|
|
16049
|
+
children: ["#", task.fireCount]
|
|
16050
|
+
})]
|
|
16051
|
+
})]
|
|
16052
|
+
}), !task.enabled && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
16053
|
+
className: "text-[10px] text-gray-600 pl-4",
|
|
16054
|
+
children: formatScheduleDescription(task)
|
|
16055
|
+
})]
|
|
16056
|
+
}, task.taskId);
|
|
16057
|
+
})]
|
|
16058
|
+
})]
|
|
16059
|
+
});
|
|
16060
|
+
};
|
|
16061
|
+
|
|
15762
16062
|
/**
|
|
15763
16063
|
* WidgetCard
|
|
15764
16064
|
*
|
|
@@ -15938,6 +16238,7 @@ var WidgetCard = function WidgetCard(_ref4) {
|
|
|
15938
16238
|
WidgetCard.Header = WidgetCardHeader_Component;
|
|
15939
16239
|
WidgetCard.Body = WidgetCardBody;
|
|
15940
16240
|
WidgetCard.Footer = WidgetCardFooter;
|
|
16241
|
+
WidgetCard.StatusBar = WidgetCardStatusBar;
|
|
15941
16242
|
|
|
15942
16243
|
var ProviderSelector = function ProviderSelector(_ref) {
|
|
15943
16244
|
var isOpen = _ref.isOpen,
|
|
@@ -18808,6 +19109,8 @@ var WidgetContainerGridItem = function WidgetContainerGridItem(_ref) {
|
|
|
18808
19109
|
}), /*#__PURE__*/jsxRuntime.jsx(WidgetCard.Footer, {
|
|
18809
19110
|
item: item,
|
|
18810
19111
|
onConfigure: handleOpenConfig
|
|
19112
|
+
}), /*#__PURE__*/jsxRuntime.jsx(WidgetCard.StatusBar, {
|
|
19113
|
+
item: item
|
|
18811
19114
|
})]
|
|
18812
19115
|
}), (item.type !== "widget") && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
18813
19116
|
children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
@@ -18869,6 +19172,8 @@ var WidgetContainerGridItem = function WidgetContainerGridItem(_ref) {
|
|
|
18869
19172
|
}), /*#__PURE__*/jsxRuntime.jsx(WidgetCard.Footer, {
|
|
18870
19173
|
item: item,
|
|
18871
19174
|
onConfigure: handleOpenConfig
|
|
19175
|
+
}), /*#__PURE__*/jsxRuntime.jsx(WidgetCard.StatusBar, {
|
|
19176
|
+
item: item
|
|
18872
19177
|
})]
|
|
18873
19178
|
}), (item.type !== "widget") && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
18874
19179
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -20052,38 +20357,48 @@ var WidgetRenderer = function WidgetRenderer(_ref) {
|
|
|
20052
20357
|
var widgetContextValue = {
|
|
20053
20358
|
widgetData: widgetData
|
|
20054
20359
|
};
|
|
20360
|
+
var hasScheduledTasks = ((config === null || config === void 0 ? void 0 : config.scheduledTasks) || []).length > 0;
|
|
20361
|
+
var widgetElement = children === null ? /*#__PURE__*/jsxRuntime.jsx(WidgetComponent, _objectSpread$m(_objectSpread$m(_objectSpread$m({
|
|
20362
|
+
id: "widget-nokids-".concat(widgetKey),
|
|
20363
|
+
listen: function listen(listeners, handlers) {
|
|
20364
|
+
return helpers.listen(listeners, handlers);
|
|
20365
|
+
},
|
|
20366
|
+
publishEvent: function publishEvent(eventName, payload) {
|
|
20367
|
+
return helpers.publishEvent(eventName, payload);
|
|
20368
|
+
},
|
|
20369
|
+
api: w
|
|
20370
|
+
}, params), userPrefs), {}, {
|
|
20371
|
+
backgroundColor: bgColor,
|
|
20372
|
+
widgetConfig: helpers.config(),
|
|
20373
|
+
widgetEventNames: helpers.events()
|
|
20374
|
+
}), "widget-nokids-".concat(widgetKey)) : /*#__PURE__*/jsxRuntime.jsx(WidgetComponent, _objectSpread$m(_objectSpread$m(_objectSpread$m({
|
|
20375
|
+
listen: function listen(listeners, handlers) {
|
|
20376
|
+
return helpers.listen(listeners, handlers);
|
|
20377
|
+
},
|
|
20378
|
+
publishEvent: function publishEvent(eventName, payload) {
|
|
20379
|
+
return helpers.publishEvent(eventName, payload);
|
|
20380
|
+
},
|
|
20381
|
+
api: w,
|
|
20382
|
+
id: "widget-kids-".concat(widgetKey)
|
|
20383
|
+
}, params), userPrefs), {}, {
|
|
20384
|
+
backgroundColor: bgColor,
|
|
20385
|
+
children: children
|
|
20386
|
+
}), "widget-kids-".concat(widgetKey));
|
|
20055
20387
|
|
|
20056
20388
|
// Wrap widget rendering with WidgetContext + error boundary
|
|
20057
20389
|
return /*#__PURE__*/jsxRuntime.jsx(WidgetContext.Provider, {
|
|
20058
20390
|
value: widgetContextValue,
|
|
20059
20391
|
children: /*#__PURE__*/jsxRuntime.jsx(WidgetErrorBoundary, {
|
|
20060
20392
|
widgetName: component,
|
|
20061
|
-
children:
|
|
20062
|
-
|
|
20063
|
-
|
|
20064
|
-
|
|
20065
|
-
|
|
20066
|
-
|
|
20067
|
-
|
|
20068
|
-
}
|
|
20069
|
-
|
|
20070
|
-
}, params), userPrefs), {}, {
|
|
20071
|
-
backgroundColor: bgColor,
|
|
20072
|
-
widgetConfig: helpers.config(),
|
|
20073
|
-
widgetEventNames: helpers.events()
|
|
20074
|
-
}), "widget-nokids-".concat(widgetKey)) : /*#__PURE__*/jsxRuntime.jsx(WidgetComponent, _objectSpread$m(_objectSpread$m(_objectSpread$m({
|
|
20075
|
-
listen: function listen(listeners, handlers) {
|
|
20076
|
-
return helpers.listen(listeners, handlers);
|
|
20077
|
-
},
|
|
20078
|
-
publishEvent: function publishEvent(eventName, payload) {
|
|
20079
|
-
return helpers.publishEvent(eventName, payload);
|
|
20080
|
-
},
|
|
20081
|
-
api: w,
|
|
20082
|
-
id: "widget-kids-".concat(widgetKey)
|
|
20083
|
-
}, params), userPrefs), {}, {
|
|
20084
|
-
backgroundColor: bgColor,
|
|
20085
|
-
children: children
|
|
20086
|
-
}), "widget-kids-".concat(widgetKey))
|
|
20393
|
+
children: hasScheduledTasks ? /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
20394
|
+
className: "flex flex-col w-full h-full min-h-0",
|
|
20395
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
20396
|
+
className: "flex-1 min-h-0 overflow-auto",
|
|
20397
|
+
children: widgetElement
|
|
20398
|
+
}), /*#__PURE__*/jsxRuntime.jsx(WidgetCardStatusBar, {
|
|
20399
|
+
item: params
|
|
20400
|
+
})]
|
|
20401
|
+
}) : widgetElement
|
|
20087
20402
|
})
|
|
20088
20403
|
});
|
|
20089
20404
|
}
|
|
@@ -45991,6 +46306,7 @@ exports.useProviderClient = useProviderClient;
|
|
|
45991
46306
|
exports.useScheduler = useScheduler;
|
|
45992
46307
|
exports.useWidgetEvents = useWidgetEvents;
|
|
45993
46308
|
exports.useWidgetProviders = useWidgetProviders;
|
|
46309
|
+
exports.useWidgetSchedulerStatus = useWidgetSchedulerStatus;
|
|
45994
46310
|
exports.validateCellMerge = validateCellMerge;
|
|
45995
46311
|
exports.validateGridCell = validateGridCell;
|
|
45996
46312
|
exports.validateGridPlacement = validateGridPlacement;
|