@buoy-gg/jotai 2.1.11 → 2.1.13
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/LICENSE +58 -0
- package/lib/commonjs/index.js +1 -91
- package/lib/commonjs/jotai/components/JotaiAtomBrowser.js +1 -300
- package/lib/commonjs/jotai/components/JotaiAtomChangeItem.js +1 -113
- package/lib/commonjs/jotai/components/JotaiAtomDetailContent.js +1 -754
- package/lib/commonjs/jotai/components/JotaiEventFilterView.js +1 -305
- package/lib/commonjs/jotai/components/JotaiIcon.js +1 -35
- package/lib/commonjs/jotai/components/JotaiModal.js +1 -567
- package/lib/commonjs/jotai/components/index.js +1 -59
- package/lib/commonjs/jotai/hooks/useJotaiAtomChanges.js +1 -83
- package/lib/commonjs/jotai/index.js +1 -85
- package/lib/commonjs/jotai/utils/jotaiStateStore.js +1 -322
- package/lib/commonjs/jotai/utils/watchAtoms.js +1 -149
- package/lib/commonjs/preset.js +1 -98
- package/lib/module/index.js +1 -74
- package/lib/module/jotai/components/JotaiAtomBrowser.js +1 -296
- package/lib/module/jotai/components/JotaiAtomChangeItem.js +1 -109
- package/lib/module/jotai/components/JotaiAtomDetailContent.js +1 -748
- package/lib/module/jotai/components/JotaiEventFilterView.js +1 -301
- package/lib/module/jotai/components/JotaiIcon.js +1 -31
- package/lib/module/jotai/components/JotaiModal.js +1 -563
- package/lib/module/jotai/components/index.js +1 -8
- package/lib/module/jotai/hooks/useJotaiAtomChanges.js +1 -79
- package/lib/module/jotai/index.js +1 -10
- package/lib/module/jotai/utils/jotaiStateStore.js +1 -318
- package/lib/module/jotai/utils/watchAtoms.js +1 -144
- package/lib/module/preset.js +1 -94
- package/package.json +10 -10
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiAtomBrowser.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiAtomChangeItem.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiAtomDetailContent.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiEventFilterView.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiIcon.d.ts.map +0 -1
- package/lib/typescript/jotai/components/JotaiModal.d.ts.map +0 -1
- package/lib/typescript/jotai/components/index.d.ts.map +0 -1
- package/lib/typescript/jotai/hooks/useJotaiAtomChanges.d.ts.map +0 -1
- package/lib/typescript/jotai/index.d.ts.map +0 -1
- package/lib/typescript/jotai/types/index.d.ts.map +0 -1
- package/lib/typescript/jotai/utils/jotaiStateStore.d.ts.map +0 -1
- package/lib/typescript/jotai/utils/watchAtoms.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
PROPRIETARY SOFTWARE LICENSE
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present Buoy. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and its source code are proprietary and confidential.
|
|
6
|
+
|
|
7
|
+
NOTICE: This is NOT open source software. This software is licensed,
|
|
8
|
+
not sold, and is protected by copyright laws and international treaties.
|
|
9
|
+
|
|
10
|
+
TERMS AND CONDITIONS:
|
|
11
|
+
|
|
12
|
+
1. LICENSE GRANT
|
|
13
|
+
Subject to the terms of this Agreement and payment of applicable fees,
|
|
14
|
+
Buoy grants you a limited, non-exclusive, non-transferable license
|
|
15
|
+
to use the compiled software packages in your applications.
|
|
16
|
+
|
|
17
|
+
2. RESTRICTIONS
|
|
18
|
+
You may NOT:
|
|
19
|
+
- Copy, modify, or distribute the source code
|
|
20
|
+
- Reverse engineer, decompile, or disassemble the software
|
|
21
|
+
- Remove or alter any proprietary notices or labels
|
|
22
|
+
- Sublicense, rent, lease, or lend the software
|
|
23
|
+
- Use the software to create competing products
|
|
24
|
+
- Share access credentials with unauthorized parties
|
|
25
|
+
|
|
26
|
+
3. OWNERSHIP
|
|
27
|
+
React Buoy retains all right, title, and interest in the software,
|
|
28
|
+
including all intellectual property rights. This license does not
|
|
29
|
+
grant you any rights to trademarks or service marks.
|
|
30
|
+
|
|
31
|
+
4. TERMINATION
|
|
32
|
+
This license is effective until terminated. Your rights under this
|
|
33
|
+
license will terminate automatically without notice if you fail to
|
|
34
|
+
comply with any of its terms. Upon termination, you must cease all
|
|
35
|
+
use and destroy all copies of the software.
|
|
36
|
+
|
|
37
|
+
5. DISCLAIMER OF WARRANTIES
|
|
38
|
+
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
|
|
39
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
40
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
41
|
+
|
|
42
|
+
6. LIMITATION OF LIABILITY
|
|
43
|
+
IN NO EVENT SHALL BUOY BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
|
|
44
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
|
|
45
|
+
CONNECTION WITH THIS LICENSE OR THE USE OF THE SOFTWARE.
|
|
46
|
+
|
|
47
|
+
7. GOVERNING LAW
|
|
48
|
+
This Agreement shall be governed by and construed in accordance with
|
|
49
|
+
the laws of the United States, without regard to its conflict of
|
|
50
|
+
law provisions.
|
|
51
|
+
|
|
52
|
+
For licensing inquiries and subscription information:
|
|
53
|
+
- Website: https://buoy.gg
|
|
54
|
+
- Email: AustinLovesWorking@gmail.com
|
|
55
|
+
|
|
56
|
+
Unauthorized reproduction or distribution of this software, or any
|
|
57
|
+
portion of it, may result in severe civil and criminal penalties,
|
|
58
|
+
and will be prosecuted to the maximum extent possible under the law.
|
package/lib/commonjs/index.js
CHANGED
|
@@ -1,91 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "JOTAI_ICON_COLOR", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function () {
|
|
9
|
-
return _JotaiIcon.JOTAI_ICON_COLOR;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, "JotaiAtomChangeItem", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () {
|
|
15
|
-
return _JotaiAtomChangeItem.JotaiAtomChangeItem;
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
Object.defineProperty(exports, "JotaiAtomDetailContent", {
|
|
19
|
-
enumerable: true,
|
|
20
|
-
get: function () {
|
|
21
|
-
return _JotaiAtomDetailContent.JotaiAtomDetailContent;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
Object.defineProperty(exports, "JotaiAtomDetailFooter", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function () {
|
|
27
|
-
return _JotaiAtomDetailContent.JotaiAtomDetailFooter;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
Object.defineProperty(exports, "JotaiIcon", {
|
|
31
|
-
enumerable: true,
|
|
32
|
-
get: function () {
|
|
33
|
-
return _JotaiIcon.JotaiIcon;
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
Object.defineProperty(exports, "JotaiModal", {
|
|
37
|
-
enumerable: true,
|
|
38
|
-
get: function () {
|
|
39
|
-
return _JotaiModal.JotaiModal;
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
Object.defineProperty(exports, "createJotaiTool", {
|
|
43
|
-
enumerable: true,
|
|
44
|
-
get: function () {
|
|
45
|
-
return _preset.createJotaiTool;
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
Object.defineProperty(exports, "isAtomWatched", {
|
|
49
|
-
enumerable: true,
|
|
50
|
-
get: function () {
|
|
51
|
-
return _watchAtoms.isAtomWatched;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
Object.defineProperty(exports, "jotaiStateStore", {
|
|
55
|
-
enumerable: true,
|
|
56
|
-
get: function () {
|
|
57
|
-
return _jotaiStateStore.jotaiStateStore;
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
Object.defineProperty(exports, "jotaiToolPreset", {
|
|
61
|
-
enumerable: true,
|
|
62
|
-
get: function () {
|
|
63
|
-
return _preset.jotaiToolPreset;
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
Object.defineProperty(exports, "useJotaiAtomChanges", {
|
|
67
|
-
enumerable: true,
|
|
68
|
-
get: function () {
|
|
69
|
-
return _useJotaiAtomChanges.useJotaiAtomChanges;
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
Object.defineProperty(exports, "watchAtoms", {
|
|
73
|
-
enumerable: true,
|
|
74
|
-
get: function () {
|
|
75
|
-
return _watchAtoms.watchAtoms;
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
Object.defineProperty(exports, "watchDefaultStoreAtoms", {
|
|
79
|
-
enumerable: true,
|
|
80
|
-
get: function () {
|
|
81
|
-
return _watchAtoms.watchDefaultStoreAtoms;
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
var _preset = require("./preset");
|
|
85
|
-
var _watchAtoms = require("./jotai/utils/watchAtoms");
|
|
86
|
-
var _useJotaiAtomChanges = require("./jotai/hooks/useJotaiAtomChanges");
|
|
87
|
-
var _JotaiModal = require("./jotai/components/JotaiModal");
|
|
88
|
-
var _JotaiAtomChangeItem = require("./jotai/components/JotaiAtomChangeItem");
|
|
89
|
-
var _JotaiAtomDetailContent = require("./jotai/components/JotaiAtomDetailContent");
|
|
90
|
-
var _JotaiIcon = require("./jotai/components/JotaiIcon");
|
|
91
|
-
var _jotaiStateStore = require("./jotai/utils/jotaiStateStore");
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"JOTAI_ICON_COLOR",{enumerable:!0,get:function(){return _JotaiIcon.JOTAI_ICON_COLOR}}),Object.defineProperty(exports,"JotaiAtomChangeItem",{enumerable:!0,get:function(){return _JotaiAtomChangeItem.JotaiAtomChangeItem}}),Object.defineProperty(exports,"JotaiAtomDetailContent",{enumerable:!0,get:function(){return _JotaiAtomDetailContent.JotaiAtomDetailContent}}),Object.defineProperty(exports,"JotaiAtomDetailFooter",{enumerable:!0,get:function(){return _JotaiAtomDetailContent.JotaiAtomDetailFooter}}),Object.defineProperty(exports,"JotaiIcon",{enumerable:!0,get:function(){return _JotaiIcon.JotaiIcon}}),Object.defineProperty(exports,"JotaiModal",{enumerable:!0,get:function(){return _JotaiModal.JotaiModal}}),Object.defineProperty(exports,"createJotaiTool",{enumerable:!0,get:function(){return _preset.createJotaiTool}}),Object.defineProperty(exports,"isAtomWatched",{enumerable:!0,get:function(){return _watchAtoms.isAtomWatched}}),Object.defineProperty(exports,"jotaiStateStore",{enumerable:!0,get:function(){return _jotaiStateStore.jotaiStateStore}}),Object.defineProperty(exports,"jotaiToolPreset",{enumerable:!0,get:function(){return _preset.jotaiToolPreset}}),Object.defineProperty(exports,"useJotaiAtomChanges",{enumerable:!0,get:function(){return _useJotaiAtomChanges.useJotaiAtomChanges}}),Object.defineProperty(exports,"watchAtoms",{enumerable:!0,get:function(){return _watchAtoms.watchAtoms}}),Object.defineProperty(exports,"watchDefaultStoreAtoms",{enumerable:!0,get:function(){return _watchAtoms.watchDefaultStoreAtoms}});var _preset=require("./preset"),_watchAtoms=require("./jotai/utils/watchAtoms"),_useJotaiAtomChanges=require("./jotai/hooks/useJotaiAtomChanges"),_JotaiModal=require("./jotai/components/JotaiModal"),_JotaiAtomChangeItem=require("./jotai/components/JotaiAtomChangeItem"),_JotaiAtomDetailContent=require("./jotai/components/JotaiAtomDetailContent"),_JotaiIcon=require("./jotai/components/JotaiIcon"),_jotaiStateStore=require("./jotai/utils/jotaiStateStore");
|
|
@@ -1,300 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.JotaiAtomBrowser = JotaiAtomBrowser;
|
|
7
|
-
var _react = require("react");
|
|
8
|
-
var _reactNative = require("react-native");
|
|
9
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
|
-
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
11
|
-
var _jotaiStateStore = require("../utils/jotaiStateStore");
|
|
12
|
-
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
-
/**
|
|
14
|
-
* JotaiAtomBrowser
|
|
15
|
-
*
|
|
16
|
-
* Atoms tab — shows all registered Jotai atoms and their current value.
|
|
17
|
-
* Mirrors ZustandStoreBrowser.tsx from @buoy-gg/zustand.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
function getValuePreview(atom) {
|
|
21
|
-
try {
|
|
22
|
-
const value = atom.getValue();
|
|
23
|
-
if (value === undefined) return "undefined";
|
|
24
|
-
if (value === null) return "null";
|
|
25
|
-
if (Array.isArray(value)) {
|
|
26
|
-
if (value.length === 0) return "[]";
|
|
27
|
-
return `[${value.length} item${value.length === 1 ? "" : "s"}]`;
|
|
28
|
-
}
|
|
29
|
-
if (typeof value === "object") {
|
|
30
|
-
const keys = Object.keys(value);
|
|
31
|
-
if (keys.length === 0) return "{}";
|
|
32
|
-
if (keys.length <= 3) return keys.join(", ");
|
|
33
|
-
return `${keys.slice(0, 2).join(", ")} +${keys.length - 2}`;
|
|
34
|
-
}
|
|
35
|
-
return String(value).slice(0, 40);
|
|
36
|
-
} catch {
|
|
37
|
-
return "";
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function getValueType(atom) {
|
|
41
|
-
try {
|
|
42
|
-
const value = atom.getValue();
|
|
43
|
-
if (value === null) return "null";
|
|
44
|
-
if (value === undefined) return "undefined";
|
|
45
|
-
if (Array.isArray(value)) return `array · ${value.length}`;
|
|
46
|
-
return typeof value;
|
|
47
|
-
} catch {
|
|
48
|
-
return "unknown";
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function AtomExpandedContent({
|
|
52
|
-
atom,
|
|
53
|
-
onViewHistory
|
|
54
|
-
}) {
|
|
55
|
-
const value = atom.getValue();
|
|
56
|
-
const displayValue = (0, _react.useMemo)(() => {
|
|
57
|
-
if (value && typeof value === "object") {
|
|
58
|
-
const filtered = {};
|
|
59
|
-
for (const [key, v] of Object.entries(value)) {
|
|
60
|
-
if (typeof v !== "function") filtered[key] = v;
|
|
61
|
-
}
|
|
62
|
-
return (0, _sharedUi.parseValue)(filtered);
|
|
63
|
-
}
|
|
64
|
-
return (0, _sharedUi.parseValue)(value);
|
|
65
|
-
}, [value]);
|
|
66
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
67
|
-
style: expandedStyles.container,
|
|
68
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ExpandedInfoRow, {
|
|
69
|
-
label: "Type",
|
|
70
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PillBadge, {
|
|
71
|
-
color: atom.color,
|
|
72
|
-
children: "JOTAI"
|
|
73
|
-
})
|
|
74
|
-
}), atom.changeCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.ExpandedInfoRow, {
|
|
75
|
-
label: "Changes",
|
|
76
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.PillBadge, {
|
|
77
|
-
color: _sharedUi.buoyColors.warning,
|
|
78
|
-
children: String(atom.changeCount)
|
|
79
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
80
|
-
onPress: () => onViewHistory(atom.label),
|
|
81
|
-
style: expandedStyles.viewHistoryButton,
|
|
82
|
-
hitSlop: {
|
|
83
|
-
top: 6,
|
|
84
|
-
bottom: 6,
|
|
85
|
-
left: 6,
|
|
86
|
-
right: 6
|
|
87
|
-
},
|
|
88
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
89
|
-
style: [expandedStyles.viewHistoryText, {
|
|
90
|
-
color: atom.color
|
|
91
|
-
}],
|
|
92
|
-
children: "view history \u2192"
|
|
93
|
-
})
|
|
94
|
-
})]
|
|
95
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
96
|
-
style: expandedStyles.dataContainer,
|
|
97
|
-
children: displayValue && typeof displayValue === "object" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
|
|
98
|
-
title: "",
|
|
99
|
-
data: displayValue,
|
|
100
|
-
showTypeFilter: true,
|
|
101
|
-
rawMode: true,
|
|
102
|
-
initialExpanded: true
|
|
103
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
104
|
-
style: expandedStyles.primitiveText,
|
|
105
|
-
children: String(value ?? "undefined")
|
|
106
|
-
})
|
|
107
|
-
})]
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
function EmptyBrowserState() {
|
|
111
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
112
|
-
style: styles.emptyState,
|
|
113
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Box, {
|
|
114
|
-
size: 32,
|
|
115
|
-
color: _sharedUi.macOSColors.text.muted
|
|
116
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
117
|
-
style: styles.emptyTitle,
|
|
118
|
-
children: "No atoms registered"
|
|
119
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
120
|
-
style: styles.emptyText,
|
|
121
|
-
children: "Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."
|
|
122
|
-
})]
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
function JotaiAtomBrowser({
|
|
126
|
-
atoms,
|
|
127
|
-
searchQuery,
|
|
128
|
-
onViewHistory
|
|
129
|
-
}) {
|
|
130
|
-
const [expandedAtom, setExpandedAtom] = (0, _react.useState)(null);
|
|
131
|
-
const filteredAtoms = (0, _react.useMemo)(() => {
|
|
132
|
-
if (!searchQuery) return atoms;
|
|
133
|
-
const search = searchQuery.toLowerCase();
|
|
134
|
-
return atoms.filter(a => a.label.toLowerCase().includes(search));
|
|
135
|
-
}, [atoms, searchQuery]);
|
|
136
|
-
const handleAtomPress = (0, _react.useCallback)(atom => {
|
|
137
|
-
setExpandedAtom(prev => prev === atom.label ? null : atom.label);
|
|
138
|
-
}, []);
|
|
139
|
-
if (filteredAtoms.length === 0 && !searchQuery) {
|
|
140
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyBrowserState, {});
|
|
141
|
-
}
|
|
142
|
-
if (filteredAtoms.length === 0 && searchQuery) {
|
|
143
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
144
|
-
style: styles.emptyState,
|
|
145
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
146
|
-
style: styles.emptyTitle,
|
|
147
|
-
children: "No matching atoms"
|
|
148
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
149
|
-
style: styles.emptyText,
|
|
150
|
-
children: ["No atoms match \"", searchQuery, "\""]
|
|
151
|
-
})]
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
|
|
155
|
-
style: styles.container,
|
|
156
|
-
contentContainerStyle: styles.scrollContent,
|
|
157
|
-
showsVerticalScrollIndicator: true,
|
|
158
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
159
|
-
style: styles.sectionHeader,
|
|
160
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
161
|
-
style: styles.sectionTitle,
|
|
162
|
-
children: "ATOMS"
|
|
163
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
164
|
-
style: styles.sectionCountBadge,
|
|
165
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
166
|
-
style: styles.sectionCountText,
|
|
167
|
-
children: filteredAtoms.length
|
|
168
|
-
})
|
|
169
|
-
})]
|
|
170
|
-
}), filteredAtoms.map(atom => {
|
|
171
|
-
const isExpanded = expandedAtom === atom.label;
|
|
172
|
-
const valuePreview = getValuePreview(atom);
|
|
173
|
-
const atomColor = _jotaiStateStore.jotaiStateStore.getAtomColor(atom.label);
|
|
174
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
175
|
-
style: styles.atomRowWrapper,
|
|
176
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
177
|
-
statusDotColor: atomColor,
|
|
178
|
-
statusLabel: atom.label,
|
|
179
|
-
statusSublabel: getValueType(atom),
|
|
180
|
-
primaryText: valuePreview,
|
|
181
|
-
showChevron: true,
|
|
182
|
-
isExpanded: isExpanded,
|
|
183
|
-
onPress: () => handleAtomPress(atom),
|
|
184
|
-
expandedContent: isExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(AtomExpandedContent, {
|
|
185
|
-
atom: atom,
|
|
186
|
-
onViewHistory: onViewHistory
|
|
187
|
-
}) : undefined
|
|
188
|
-
}), atom.changeCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
189
|
-
style: [styles.absCountBadge, {
|
|
190
|
-
backgroundColor: atomColor + "22",
|
|
191
|
-
borderColor: atomColor + "55"
|
|
192
|
-
}],
|
|
193
|
-
pointerEvents: "none",
|
|
194
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
195
|
-
style: [styles.absCountText, {
|
|
196
|
-
color: atomColor
|
|
197
|
-
}],
|
|
198
|
-
children: String(atom.changeCount)
|
|
199
|
-
})
|
|
200
|
-
})]
|
|
201
|
-
}, atom.label);
|
|
202
|
-
})]
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
const styles = _reactNative.StyleSheet.create({
|
|
206
|
-
container: {
|
|
207
|
-
flex: 1
|
|
208
|
-
},
|
|
209
|
-
atomRowWrapper: {
|
|
210
|
-
position: "relative"
|
|
211
|
-
},
|
|
212
|
-
absCountBadge: {
|
|
213
|
-
position: "absolute",
|
|
214
|
-
top: 4,
|
|
215
|
-
right: 10,
|
|
216
|
-
paddingHorizontal: 5,
|
|
217
|
-
paddingVertical: 1,
|
|
218
|
-
borderRadius: 4,
|
|
219
|
-
borderWidth: 1,
|
|
220
|
-
zIndex: 1
|
|
221
|
-
},
|
|
222
|
-
absCountText: {
|
|
223
|
-
fontSize: 9,
|
|
224
|
-
fontWeight: "700",
|
|
225
|
-
fontFamily: "monospace"
|
|
226
|
-
},
|
|
227
|
-
scrollContent: {
|
|
228
|
-
paddingTop: 8,
|
|
229
|
-
paddingBottom: 20
|
|
230
|
-
},
|
|
231
|
-
sectionHeader: {
|
|
232
|
-
flexDirection: "row",
|
|
233
|
-
alignItems: "center",
|
|
234
|
-
paddingHorizontal: 16,
|
|
235
|
-
paddingVertical: 8,
|
|
236
|
-
gap: 8
|
|
237
|
-
},
|
|
238
|
-
sectionTitle: {
|
|
239
|
-
fontSize: 11,
|
|
240
|
-
fontWeight: "700",
|
|
241
|
-
letterSpacing: 0.5,
|
|
242
|
-
color: _sharedUi.macOSColors.text.muted
|
|
243
|
-
},
|
|
244
|
-
sectionCountBadge: {
|
|
245
|
-
backgroundColor: _sharedUi.buoyColors.primary + "26",
|
|
246
|
-
paddingHorizontal: 8,
|
|
247
|
-
paddingVertical: 2,
|
|
248
|
-
borderRadius: 4
|
|
249
|
-
},
|
|
250
|
-
sectionCountText: {
|
|
251
|
-
fontSize: 10,
|
|
252
|
-
fontWeight: "700",
|
|
253
|
-
color: _sharedUi.buoyColors.primary,
|
|
254
|
-
fontFamily: "monospace"
|
|
255
|
-
},
|
|
256
|
-
emptyState: {
|
|
257
|
-
alignItems: "center",
|
|
258
|
-
paddingVertical: 40
|
|
259
|
-
},
|
|
260
|
-
emptyTitle: {
|
|
261
|
-
color: _sharedUi.macOSColors.text.primary,
|
|
262
|
-
fontSize: 14,
|
|
263
|
-
fontWeight: "600",
|
|
264
|
-
marginTop: 12,
|
|
265
|
-
marginBottom: 6
|
|
266
|
-
},
|
|
267
|
-
emptyText: {
|
|
268
|
-
color: _sharedUi.macOSColors.text.muted,
|
|
269
|
-
fontSize: 12,
|
|
270
|
-
textAlign: "center",
|
|
271
|
-
lineHeight: 18
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
const expandedStyles = _reactNative.StyleSheet.create({
|
|
275
|
-
container: {
|
|
276
|
-
gap: 10
|
|
277
|
-
},
|
|
278
|
-
viewHistoryButton: {
|
|
279
|
-
marginLeft: 4
|
|
280
|
-
},
|
|
281
|
-
viewHistoryText: {
|
|
282
|
-
fontSize: 10,
|
|
283
|
-
fontWeight: "600",
|
|
284
|
-
fontFamily: "monospace"
|
|
285
|
-
},
|
|
286
|
-
dataContainer: {
|
|
287
|
-
backgroundColor: _sharedUi.buoyColors.base,
|
|
288
|
-
borderRadius: 6,
|
|
289
|
-
borderWidth: 1,
|
|
290
|
-
borderColor: _sharedUi.buoyColors.border,
|
|
291
|
-
overflow: "hidden",
|
|
292
|
-
minHeight: 60
|
|
293
|
-
},
|
|
294
|
-
primitiveText: {
|
|
295
|
-
color: _sharedUi.buoyColors.text,
|
|
296
|
-
fontSize: 12,
|
|
297
|
-
fontFamily: "monospace",
|
|
298
|
-
padding: 14
|
|
299
|
-
}
|
|
300
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JotaiAtomBrowser=JotaiAtomBrowser;var _react=require("react"),_reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_dataViewer=require("@buoy-gg/shared-ui/dataViewer"),_jotaiStateStore=require("../utils/jotaiStateStore"),_jsxRuntime=require("react/jsx-runtime");function getValuePreview(e){try{const t=e.getValue();if(void 0===t)return"undefined";if(null===t)return"null";if(Array.isArray(t))return 0===t.length?"[]":`[${t.length} item${1===t.length?"":"s"}]`;if("object"==typeof t){const e=Object.keys(t);return 0===e.length?"{}":e.length<=3?e.join(", "):`${e.slice(0,2).join(", ")} +${e.length-2}`}return String(t).slice(0,40)}catch{return""}}function getValueType(e){try{const t=e.getValue();return null===t?"null":void 0===t?"undefined":Array.isArray(t)?`array · ${t.length}`:typeof t}catch{return"unknown"}}function AtomExpandedContent({atom:e,onViewHistory:t}){const r=e.getValue(),i=(0,_react.useMemo)(()=>{if(r&&"object"==typeof r){const e={};for(const[t,i]of Object.entries(r))"function"!=typeof i&&(e[t]=i);return(0,_sharedUi.parseValue)(e)}return(0,_sharedUi.parseValue)(r)},[r]);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:expandedStyles.container,children:[(0,_jsxRuntime.jsx)(_sharedUi.ExpandedInfoRow,{label:"Type",children:(0,_jsxRuntime.jsx)(_sharedUi.PillBadge,{color:e.color,children:"JOTAI"})}),e.changeCount>0&&(0,_jsxRuntime.jsxs)(_sharedUi.ExpandedInfoRow,{label:"Changes",children:[(0,_jsxRuntime.jsx)(_sharedUi.PillBadge,{color:_sharedUi.buoyColors.warning,children:String(e.changeCount)}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>t(e.label),style:expandedStyles.viewHistoryButton,hitSlop:{top:6,bottom:6,left:6,right:6},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[expandedStyles.viewHistoryText,{color:e.color}],children:"view history →"})})]}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:expandedStyles.dataContainer,children:i&&"object"==typeof i?(0,_jsxRuntime.jsx)(_dataViewer.DataViewer,{title:"",data:i,showTypeFilter:!0,rawMode:!0,initialExpanded:!0}):(0,_jsxRuntime.jsx)(_reactNative.Text,{style:expandedStyles.primitiveText,children:String(r??"undefined")})})]})}function EmptyBrowserState(){return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_sharedUi.Box,{size:32,color:_sharedUi.macOSColors.text.muted}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyTitle,children:"No atoms registered"}),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyText,children:"Use watchAtoms(store, { atomName }) to register your Jotai atoms.\nThey will appear here with their current value."})]})}function JotaiAtomBrowser({atoms:e,searchQuery:t,onViewHistory:r}){const[i,o]=(0,_react.useState)(null),a=(0,_react.useMemo)(()=>{if(!t)return e;const r=t.toLowerCase();return e.filter(e=>e.label.toLowerCase().includes(r))},[e,t]),n=(0,_react.useCallback)(e=>{o(t=>t===e.label?null:e.label)},[]);return 0!==a.length||t?0===a.length&&t?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.emptyState,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.emptyTitle,children:"No matching atoms"}),(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.emptyText,children:['No atoms match "',t,'"']})]}):(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{style:styles.container,contentContainerStyle:styles.scrollContent,showsVerticalScrollIndicator:!0,children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.sectionHeader,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionTitle,children:"ATOMS"}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.sectionCountBadge,children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.sectionCountText,children:a.length})})]}),a.map(e=>{const t=i===e.label,o=getValuePreview(e),a=_jotaiStateStore.jotaiStateStore.getAtomColor(e.label);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.atomRowWrapper,children:[(0,_jsxRuntime.jsx)(_sharedUi.CompactRow,{statusDotColor:a,statusLabel:e.label,statusSublabel:getValueType(e),primaryText:o,showChevron:!0,isExpanded:t,onPress:()=>n(e),expandedContent:t?(0,_jsxRuntime.jsx)(AtomExpandedContent,{atom:e,onViewHistory:r}):void 0}),e.changeCount>0&&(0,_jsxRuntime.jsx)(_reactNative.View,{style:[styles.absCountBadge,{backgroundColor:a+"22",borderColor:a+"55"}],pointerEvents:"none",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.absCountText,{color:a}],children:String(e.changeCount)})})]},e.label)})]}):(0,_jsxRuntime.jsx)(EmptyBrowserState,{})}const styles=_reactNative.StyleSheet.create({container:{flex:1},atomRowWrapper:{position:"relative"},absCountBadge:{position:"absolute",top:4,right:10,paddingHorizontal:5,paddingVertical:1,borderRadius:4,borderWidth:1,zIndex:1},absCountText:{fontSize:9,fontWeight:"700",fontFamily:"monospace"},scrollContent:{paddingTop:8,paddingBottom:20},sectionHeader:{flexDirection:"row",alignItems:"center",paddingHorizontal:16,paddingVertical:8,gap:8},sectionTitle:{fontSize:11,fontWeight:"700",letterSpacing:.5,color:_sharedUi.macOSColors.text.muted},sectionCountBadge:{backgroundColor:_sharedUi.buoyColors.primary+"26",paddingHorizontal:8,paddingVertical:2,borderRadius:4},sectionCountText:{fontSize:10,fontWeight:"700",color:_sharedUi.buoyColors.primary,fontFamily:"monospace"},emptyState:{alignItems:"center",paddingVertical:40},emptyTitle:{color:_sharedUi.macOSColors.text.primary,fontSize:14,fontWeight:"600",marginTop:12,marginBottom:6},emptyText:{color:_sharedUi.macOSColors.text.muted,fontSize:12,textAlign:"center",lineHeight:18}}),expandedStyles=_reactNative.StyleSheet.create({container:{gap:10},viewHistoryButton:{marginLeft:4},viewHistoryText:{fontSize:10,fontWeight:"600",fontFamily:"monospace"},dataContainer:{backgroundColor:_sharedUi.buoyColors.base,borderRadius:6,borderWidth:1,borderColor:_sharedUi.buoyColors.border,overflow:"hidden",minHeight:60},primitiveText:{color:_sharedUi.buoyColors.text,fontSize:12,fontFamily:"monospace",padding:14}});
|
|
@@ -1,113 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.JotaiAtomChangeItem = JotaiAtomChangeItem;
|
|
7
|
-
var _reactNative = require("react-native");
|
|
8
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
|
-
var _jotaiStateStore = require("../utils/jotaiStateStore");
|
|
10
|
-
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
-
/**
|
|
12
|
-
* Compact list item for displaying a Jotai atom change
|
|
13
|
-
*
|
|
14
|
-
* Mirrors ZustandStateChangeItem.tsx — uses shared CompactRow for consistent styling
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
function getStatusLabel(category, atomLabel) {
|
|
18
|
-
if (category === "initial") return "Initial";
|
|
19
|
-
return atomLabel.charAt(0).toUpperCase() + atomLabel.slice(1);
|
|
20
|
-
}
|
|
21
|
-
function getCategoryColor(category, atomLabel) {
|
|
22
|
-
if (category === "initial") return _sharedUi.buoyColors.textMuted;
|
|
23
|
-
return _jotaiStateStore.jotaiStateStore.getAtomColor(atomLabel);
|
|
24
|
-
}
|
|
25
|
-
function formatCompact(value, maxLen = 20) {
|
|
26
|
-
if (value === undefined) return "undefined";
|
|
27
|
-
if (value === null) return "null";
|
|
28
|
-
if (typeof value === "boolean") return String(value);
|
|
29
|
-
if (typeof value === "number") return String(value);
|
|
30
|
-
if (typeof value === "string") {
|
|
31
|
-
const truncated = value.length > maxLen ? value.slice(0, maxLen - 1) + "…" : value;
|
|
32
|
-
return `"${truncated}"`;
|
|
33
|
-
}
|
|
34
|
-
if (Array.isArray(value)) {
|
|
35
|
-
return value.length === 0 ? "[]" : `[${value.length} item${value.length === 1 ? "" : "s"}]`;
|
|
36
|
-
}
|
|
37
|
-
if (typeof value === "object") {
|
|
38
|
-
const keys = Object.keys(value);
|
|
39
|
-
if (keys.length === 0) return "{}";
|
|
40
|
-
return `{${keys.slice(0, 2).join(", ")}${keys.length > 2 ? "…" : ""}}`;
|
|
41
|
-
}
|
|
42
|
-
return String(value).slice(0, maxLen);
|
|
43
|
-
}
|
|
44
|
-
function getSublabel(change) {
|
|
45
|
-
if (!change.hasValueChange) return "no change";
|
|
46
|
-
return `${formatCompact(change.prevValue)} → ${formatCompact(change.nextValue)}`;
|
|
47
|
-
}
|
|
48
|
-
function getBadgeText(change) {
|
|
49
|
-
if (change.category === "initial") return "INIT";
|
|
50
|
-
return "WRITE";
|
|
51
|
-
}
|
|
52
|
-
function getPrimaryText(change) {
|
|
53
|
-
if (change.changedKeys.length > 0 && change.changedKeys.length <= 3) {
|
|
54
|
-
return change.changedKeys.join(", ");
|
|
55
|
-
}
|
|
56
|
-
if (change.changedKeys.length > 3) {
|
|
57
|
-
return `${change.changedKeys.slice(0, 2).join(", ")} +${change.changedKeys.length - 2}`;
|
|
58
|
-
}
|
|
59
|
-
return change.valuePreview || "atom()";
|
|
60
|
-
}
|
|
61
|
-
function JotaiAtomChangeItem({
|
|
62
|
-
change,
|
|
63
|
-
onPress
|
|
64
|
-
}) {
|
|
65
|
-
const statusColor = getCategoryColor(change.category, change.atomLabel);
|
|
66
|
-
const statusLabel = getStatusLabel(change.category, change.atomLabel);
|
|
67
|
-
const sublabel = getSublabel(change);
|
|
68
|
-
const primaryText = getPrimaryText(change);
|
|
69
|
-
const badgeText = getBadgeText(change);
|
|
70
|
-
const relativeTime = (0, _sharedUi.useRelativeTime)(change.timestamp);
|
|
71
|
-
const customBadge = change.hasValueChange ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
72
|
-
style: styles.badgeContainer,
|
|
73
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
74
|
-
style: [styles.badgeText, {
|
|
75
|
-
color: statusColor
|
|
76
|
-
}],
|
|
77
|
-
children: badgeText
|
|
78
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
79
|
-
style: styles.changeBadge,
|
|
80
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
81
|
-
size: 12,
|
|
82
|
-
color: _sharedUi.buoyColors.warning
|
|
83
|
-
})
|
|
84
|
-
})]
|
|
85
|
-
}) : undefined;
|
|
86
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
87
|
-
statusDotColor: statusColor,
|
|
88
|
-
statusLabel: statusLabel,
|
|
89
|
-
statusSublabel: sublabel,
|
|
90
|
-
primaryText: primaryText,
|
|
91
|
-
bottomRightText: relativeTime,
|
|
92
|
-
customBadge: customBadge,
|
|
93
|
-
badgeText: customBadge ? undefined : badgeText,
|
|
94
|
-
badgeColor: statusColor,
|
|
95
|
-
showChevron: true,
|
|
96
|
-
onPress: () => onPress(change)
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
const styles = _reactNative.StyleSheet.create({
|
|
100
|
-
badgeContainer: {
|
|
101
|
-
flexDirection: "row",
|
|
102
|
-
alignItems: "center",
|
|
103
|
-
gap: 4
|
|
104
|
-
},
|
|
105
|
-
badgeText: {
|
|
106
|
-
fontSize: 11,
|
|
107
|
-
fontWeight: "600",
|
|
108
|
-
fontFamily: "monospace"
|
|
109
|
-
},
|
|
110
|
-
changeBadge: {
|
|
111
|
-
paddingHorizontal: 4
|
|
112
|
-
}
|
|
113
|
-
});
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.JotaiAtomChangeItem=JotaiAtomChangeItem;var _reactNative=require("react-native"),_sharedUi=require("@buoy-gg/shared-ui"),_jotaiStateStore=require("../utils/jotaiStateStore"),_jsxRuntime=require("react/jsx-runtime");function getStatusLabel(e,t){return"initial"===e?"Initial":t.charAt(0).toUpperCase()+t.slice(1)}function getCategoryColor(e,t){return"initial"===e?_sharedUi.buoyColors.textMuted:_jotaiStateStore.jotaiStateStore.getAtomColor(t)}function formatCompact(e,t=20){if(void 0===e)return"undefined";if(null===e)return"null";if("boolean"==typeof e)return String(e);if("number"==typeof e)return String(e);if("string"==typeof e)return`"${e.length>t?e.slice(0,t-1)+"…":e}"`;if(Array.isArray(e))return 0===e.length?"[]":`[${e.length} item${1===e.length?"":"s"}]`;if("object"==typeof e){const t=Object.keys(e);return 0===t.length?"{}":`{${t.slice(0,2).join(", ")}${t.length>2?"…":""}}`}return String(e).slice(0,t)}function getSublabel(e){return e.hasValueChange?`${formatCompact(e.prevValue)} → ${formatCompact(e.nextValue)}`:"no change"}function getBadgeText(e){return"initial"===e.category?"INIT":"WRITE"}function getPrimaryText(e){return e.changedKeys.length>0&&e.changedKeys.length<=3?e.changedKeys.join(", "):e.changedKeys.length>3?`${e.changedKeys.slice(0,2).join(", ")} +${e.changedKeys.length-2}`:e.valuePreview||"atom()"}function JotaiAtomChangeItem({change:e,onPress:t}){const a=getCategoryColor(e.category,e.atomLabel),r=getStatusLabel(e.category,e.atomLabel),n=getSublabel(e),i=getPrimaryText(e),o=getBadgeText(e),s=(0,_sharedUi.useRelativeTime)(e.timestamp),l=e.hasValueChange?(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.badgeContainer,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[styles.badgeText,{color:a}],children:o}),(0,_jsxRuntime.jsx)(_reactNative.View,{style:styles.changeBadge,children:(0,_jsxRuntime.jsx)(_sharedUi.Zap,{size:12,color:_sharedUi.buoyColors.warning})})]}):void 0;return(0,_jsxRuntime.jsx)(_sharedUi.CompactRow,{statusDotColor:a,statusLabel:r,statusSublabel:n,primaryText:i,bottomRightText:s,customBadge:l,badgeText:l?void 0:o,badgeColor:a,showChevron:!0,onPress:()=>t(e)})}const styles=_reactNative.StyleSheet.create({badgeContainer:{flexDirection:"row",alignItems:"center",gap:4},badgeText:{fontSize:11,fontWeight:"600",fontFamily:"monospace"},changeBadge:{paddingHorizontal:4}});
|