@buoy-gg/shared-ui 7.0.22 → 7.0.24
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/lib/commonjs/JsModal.js +39 -16
- package/lib/commonjs/dataViewer/JsonStringNotice.js +59 -0
- package/lib/commonjs/dataViewer/ThemedSplitView.js +20 -1
- package/lib/commonjs/dataViewer/TimestampDeltaBar.js +96 -0
- package/lib/commonjs/dataViewer/index.js +52 -0
- package/lib/commonjs/dataViewer/jsonStringValue.js +94 -0
- package/lib/commonjs/dataViewer/timestampDiff.js +146 -0
- package/lib/commonjs/hooks/safe-area-impl.js +1 -1
- package/lib/commonjs/index.js +50 -1
- package/lib/commonjs/license/FeatureGate.js +43 -10
- package/lib/commonjs/license/FreeAccountPrompt.js +181 -0
- package/lib/commonjs/license/index.js +57 -42
- package/lib/commonjs/license/licenseModule.js +99 -0
- package/lib/commonjs/license/tierLimits.js +165 -0
- package/lib/commonjs/ui/backgrounds/BackgroundSwitcher.js +180 -0
- package/lib/commonjs/ui/backgrounds/README.md +115 -0
- package/lib/commonjs/ui/backgrounds/ToolBackground.js +74 -0
- package/lib/commonjs/ui/backgrounds/backgroundStore.js +116 -0
- package/lib/commonjs/ui/backgrounds/index.js +70 -0
- package/lib/commonjs/ui/backgrounds/primitives.js +333 -0
- package/lib/commonjs/ui/backgrounds/registry.js +112 -0
- package/lib/commonjs/ui/backgrounds/rng.js +72 -0
- package/lib/commonjs/ui/backgrounds/types.js +1 -0
- package/lib/commonjs/ui/backgrounds/variants/deepField.js +351 -0
- package/lib/commonjs/ui/backgrounds/variants/lattice.js +579 -0
- package/lib/commonjs/ui/backgrounds/variants/starfield.js +210 -0
- package/lib/commonjs/ui/index.js +15 -3
- package/lib/module/JsModal.js +39 -16
- package/lib/module/dataViewer/JsonStringNotice.js +54 -0
- package/lib/module/dataViewer/ThemedSplitView.js +20 -1
- package/lib/module/dataViewer/TimestampDeltaBar.js +91 -0
- package/lib/module/dataViewer/index.js +4 -0
- package/lib/module/dataViewer/jsonStringValue.js +89 -0
- package/lib/module/dataViewer/timestampDiff.js +139 -0
- package/lib/module/hooks/safe-area-impl.js +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/license/FeatureGate.js +43 -10
- package/lib/module/license/FreeAccountPrompt.js +176 -0
- package/lib/module/license/index.js +5 -40
- package/lib/module/license/licenseModule.js +92 -0
- package/lib/module/license/tierLimits.js +158 -0
- package/lib/module/ui/backgrounds/BackgroundSwitcher.js +176 -0
- package/lib/module/ui/backgrounds/README.md +115 -0
- package/lib/module/ui/backgrounds/ToolBackground.js +70 -0
- package/lib/module/ui/backgrounds/backgroundStore.js +111 -0
- package/lib/module/ui/backgrounds/index.js +9 -0
- package/lib/module/ui/backgrounds/primitives.js +328 -0
- package/lib/module/ui/backgrounds/registry.js +105 -0
- package/lib/module/ui/backgrounds/rng.js +65 -0
- package/lib/module/ui/backgrounds/types.js +1 -0
- package/lib/module/ui/backgrounds/variants/deepField.js +347 -0
- package/lib/module/ui/backgrounds/variants/lattice.js +575 -0
- package/lib/module/ui/backgrounds/variants/starfield.js +206 -0
- package/lib/module/ui/index.js +3 -0
- package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/dataViewer/JsonStringNotice.d.ts +6 -0
- package/lib/typescript/commonjs/dataViewer/JsonStringNotice.d.ts.map +1 -0
- package/lib/typescript/commonjs/dataViewer/ThemedSplitView.d.ts.map +1 -1
- package/lib/typescript/commonjs/dataViewer/TimestampDeltaBar.d.ts +7 -0
- package/lib/typescript/commonjs/dataViewer/TimestampDeltaBar.d.ts.map +1 -0
- package/lib/typescript/commonjs/dataViewer/index.d.ts +6 -0
- package/lib/typescript/commonjs/dataViewer/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/dataViewer/jsonStringValue.d.ts +25 -0
- package/lib/typescript/commonjs/dataViewer/jsonStringValue.d.ts.map +1 -0
- package/lib/typescript/commonjs/dataViewer/timestampDiff.d.ts +55 -0
- package/lib/typescript/commonjs/dataViewer/timestampDiff.d.ts.map +1 -0
- package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -2
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/FeatureGate.d.ts +19 -3
- package/lib/typescript/commonjs/license/FeatureGate.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts +23 -0
- package/lib/typescript/commonjs/license/FreeAccountPrompt.d.ts.map +1 -0
- package/lib/typescript/commonjs/license/index.d.ts +6 -15
- package/lib/typescript/commonjs/license/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/licenseModule.d.ts +55 -0
- package/lib/typescript/commonjs/license/licenseModule.d.ts.map +1 -0
- package/lib/typescript/commonjs/license/tierLimits.d.ts +143 -0
- package/lib/typescript/commonjs/license/tierLimits.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/BackgroundSwitcher.d.ts +13 -0
- package/lib/typescript/commonjs/ui/backgrounds/BackgroundSwitcher.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts +30 -0
- package/lib/typescript/commonjs/ui/backgrounds/ToolBackground.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/backgroundStore.d.ts +43 -0
- package/lib/typescript/commonjs/ui/backgrounds/backgroundStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/index.d.ts +7 -0
- package/lib/typescript/commonjs/ui/backgrounds/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/primitives.d.ts +106 -0
- package/lib/typescript/commonjs/ui/backgrounds/primitives.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/registry.d.ts +28 -0
- package/lib/typescript/commonjs/ui/backgrounds/registry.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/rng.d.ts +27 -0
- package/lib/typescript/commonjs/ui/backgrounds/rng.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/types.d.ts +14 -0
- package/lib/typescript/commonjs/ui/backgrounds/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/deepField.d.ts +65 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/deepField.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/lattice.d.ts +33 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/lattice.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/starfield.d.ts +12 -0
- package/lib/typescript/commonjs/ui/backgrounds/variants/starfield.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/index.d.ts +1 -0
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/JsModal.d.ts.map +1 -1
- package/lib/typescript/module/dataViewer/JsonStringNotice.d.ts +6 -0
- package/lib/typescript/module/dataViewer/JsonStringNotice.d.ts.map +1 -0
- package/lib/typescript/module/dataViewer/ThemedSplitView.d.ts.map +1 -1
- package/lib/typescript/module/dataViewer/TimestampDeltaBar.d.ts +7 -0
- package/lib/typescript/module/dataViewer/TimestampDeltaBar.d.ts.map +1 -0
- package/lib/typescript/module/dataViewer/index.d.ts +6 -0
- package/lib/typescript/module/dataViewer/index.d.ts.map +1 -1
- package/lib/typescript/module/dataViewer/jsonStringValue.d.ts +25 -0
- package/lib/typescript/module/dataViewer/jsonStringValue.d.ts.map +1 -0
- package/lib/typescript/module/dataViewer/timestampDiff.d.ts +55 -0
- package/lib/typescript/module/dataViewer/timestampDiff.d.ts.map +1 -0
- package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/module/index.d.ts +2 -2
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/license/FeatureGate.d.ts +19 -3
- package/lib/typescript/module/license/FeatureGate.d.ts.map +1 -1
- package/lib/typescript/module/license/FreeAccountPrompt.d.ts +23 -0
- package/lib/typescript/module/license/FreeAccountPrompt.d.ts.map +1 -0
- package/lib/typescript/module/license/index.d.ts +6 -15
- package/lib/typescript/module/license/index.d.ts.map +1 -1
- package/lib/typescript/module/license/licenseModule.d.ts +55 -0
- package/lib/typescript/module/license/licenseModule.d.ts.map +1 -0
- package/lib/typescript/module/license/tierLimits.d.ts +143 -0
- package/lib/typescript/module/license/tierLimits.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/BackgroundSwitcher.d.ts +13 -0
- package/lib/typescript/module/ui/backgrounds/BackgroundSwitcher.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts +30 -0
- package/lib/typescript/module/ui/backgrounds/ToolBackground.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/backgroundStore.d.ts +43 -0
- package/lib/typescript/module/ui/backgrounds/backgroundStore.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/index.d.ts +7 -0
- package/lib/typescript/module/ui/backgrounds/index.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/primitives.d.ts +106 -0
- package/lib/typescript/module/ui/backgrounds/primitives.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/registry.d.ts +28 -0
- package/lib/typescript/module/ui/backgrounds/registry.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/rng.d.ts +27 -0
- package/lib/typescript/module/ui/backgrounds/rng.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/types.d.ts +14 -0
- package/lib/typescript/module/ui/backgrounds/types.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/variants/deepField.d.ts +65 -0
- package/lib/typescript/module/ui/backgrounds/variants/deepField.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/variants/lattice.d.ts +33 -0
- package/lib/typescript/module/ui/backgrounds/variants/lattice.d.ts.map +1 -0
- package/lib/typescript/module/ui/backgrounds/variants/starfield.d.ts +12 -0
- package/lib/typescript/module/ui/backgrounds/variants/starfield.d.ts.map +1 -0
- package/lib/typescript/module/ui/index.d.ts +1 -0
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/package.json +4 -4
- package/scripts/detect-safe-area.js +0 -20
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Starfield = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _absoluteFill = require("../../../utils/absoluteFill.js");
|
|
10
|
+
var _primitives = require("../primitives.js");
|
|
11
|
+
var _rng = require("../rng.js");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
/**
|
|
14
|
+
* Starfield — the RN-primitive port of the Everlights parallax-drift starfield.
|
|
15
|
+
*
|
|
16
|
+
* The original is a GPU-instanced Skia `<Atlas>` with a per-star worklet; Buoy
|
|
17
|
+
* can't depend on Skia, so the depth continuum is quantised into five discrete
|
|
18
|
+
* bands. Each band is one rasterized layer of dots sliding at its own speed —
|
|
19
|
+
* five native-driven loops instead of 160 per-frame transforms — and the eye
|
|
20
|
+
* reads five parallax speeds as depth just as well as it reads a continuum.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Depth bands, far → near. `z` drives both size and speed (drift/sec at z=1 is
|
|
25
|
+
* 0.016 of the width, matching the original), `count` thins out as stars get
|
|
26
|
+
* closer so the fast, big ones stay sparse.
|
|
27
|
+
*/
|
|
28
|
+
const BANDS = [
|
|
29
|
+
// dia is the star's core in px; halo is how many core-widths the bloom
|
|
30
|
+
// spreads (0 = no bloom, which is what keeps the far bands cheap).
|
|
31
|
+
{
|
|
32
|
+
z: 1.0,
|
|
33
|
+
count: 38,
|
|
34
|
+
dia: 1.4,
|
|
35
|
+
halo: 0,
|
|
36
|
+
color: "#7C93B5",
|
|
37
|
+
alpha: 0.55
|
|
38
|
+
}, {
|
|
39
|
+
z: 0.78,
|
|
40
|
+
count: 26,
|
|
41
|
+
dia: 1.9,
|
|
42
|
+
halo: 0,
|
|
43
|
+
color: "#A6BBD8",
|
|
44
|
+
alpha: 0.65
|
|
45
|
+
}, {
|
|
46
|
+
z: 0.6,
|
|
47
|
+
count: 18,
|
|
48
|
+
dia: 2.4,
|
|
49
|
+
halo: 0,
|
|
50
|
+
color: "#C9D9F0",
|
|
51
|
+
alpha: 0.8
|
|
52
|
+
}, {
|
|
53
|
+
z: 0.45,
|
|
54
|
+
count: 11,
|
|
55
|
+
dia: 3.1,
|
|
56
|
+
halo: 0,
|
|
57
|
+
color: "#E4EEFC",
|
|
58
|
+
alpha: 0.92
|
|
59
|
+
},
|
|
60
|
+
// Only the closest band gets a bloom: 6 stars x 3 extra discs is 36 views,
|
|
61
|
+
// and it is the entire difference between "dots" and "stars".
|
|
62
|
+
{
|
|
63
|
+
z: 0.3,
|
|
64
|
+
count: 6,
|
|
65
|
+
dia: 4.2,
|
|
66
|
+
halo: 4.4,
|
|
67
|
+
color: "#FFFFFF",
|
|
68
|
+
alpha: 1
|
|
69
|
+
}];
|
|
70
|
+
const DRIFT = 0.016; // fraction of width travelled per second at z=1
|
|
71
|
+
|
|
72
|
+
/** Pre-scattered x/y per band, generated once at module load. */
|
|
73
|
+
const BAND_TABLES = BANDS.map((b, i) => ({
|
|
74
|
+
xs: (0, _rng.scatter)(0x5747 + i * 977, b.count),
|
|
75
|
+
ys: (0, _rng.scatter)(0x91c3 + i * 613, b.count)
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The bloom around a close star. Three nested discs rather than a `RadialGlow`,
|
|
80
|
+
* because this one is drawn per star and lives INSIDE the band layer — which is
|
|
81
|
+
* the point: the halo travels with its star instead of sitting still while the
|
|
82
|
+
* star drifts off it.
|
|
83
|
+
*/
|
|
84
|
+
function haloDiscs(cx, cy, core, spread, color, key) {
|
|
85
|
+
const out = [];
|
|
86
|
+
const steps = [{
|
|
87
|
+
mul: spread,
|
|
88
|
+
alpha: 0.05
|
|
89
|
+
}, {
|
|
90
|
+
mul: spread * 0.62,
|
|
91
|
+
alpha: 0.09
|
|
92
|
+
}, {
|
|
93
|
+
mul: spread * 0.34,
|
|
94
|
+
alpha: 0.16
|
|
95
|
+
}];
|
|
96
|
+
for (let i = 0; i < steps.length; i++) {
|
|
97
|
+
const d = core * steps[i].mul;
|
|
98
|
+
out.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
99
|
+
style: {
|
|
100
|
+
position: "absolute",
|
|
101
|
+
left: cx - d / 2,
|
|
102
|
+
top: cy - d / 2,
|
|
103
|
+
width: d,
|
|
104
|
+
height: d,
|
|
105
|
+
borderRadius: d / 2,
|
|
106
|
+
backgroundColor: (0, _rng.withAlpha)(color, steps[i].alpha)
|
|
107
|
+
}
|
|
108
|
+
}, `${key}-h${i}`));
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
const StarBand = /*#__PURE__*/(0, _react.memo)(function StarBand({
|
|
113
|
+
index,
|
|
114
|
+
width,
|
|
115
|
+
height,
|
|
116
|
+
animated
|
|
117
|
+
}) {
|
|
118
|
+
const band = BANDS[index];
|
|
119
|
+
const table = BAND_TABLES[index];
|
|
120
|
+
// One full width of travel takes z / DRIFT seconds — nearer (smaller z) is
|
|
121
|
+
// faster, which is the whole parallax effect.
|
|
122
|
+
const drift = (0, _primitives.useLoop)(band.z / DRIFT * 1000, animated);
|
|
123
|
+
const translateX = drift.interpolate({
|
|
124
|
+
inputRange: [0, 1],
|
|
125
|
+
outputRange: [0, -width]
|
|
126
|
+
});
|
|
127
|
+
const dots = [];
|
|
128
|
+
for (let i = 0; i < band.count; i++) {
|
|
129
|
+
const x = table.xs[i] * width;
|
|
130
|
+
const y = table.ys[i] * height;
|
|
131
|
+
// Each star is drawn twice, one width apart, so the layer tiles seamlessly
|
|
132
|
+
// when the loop snaps back to 0.
|
|
133
|
+
for (let copy = 0; copy < 2; copy++) {
|
|
134
|
+
const cx = x + copy * width;
|
|
135
|
+
const key = `${i}-${copy}`;
|
|
136
|
+
if (band.halo > 0) {
|
|
137
|
+
dots.push(...haloDiscs(cx, y, band.dia, band.halo, band.color, key));
|
|
138
|
+
}
|
|
139
|
+
dots.push(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
140
|
+
style: {
|
|
141
|
+
position: "absolute",
|
|
142
|
+
left: cx - band.dia / 2,
|
|
143
|
+
top: y - band.dia / 2,
|
|
144
|
+
width: band.dia,
|
|
145
|
+
height: band.dia,
|
|
146
|
+
borderRadius: band.dia / 2,
|
|
147
|
+
backgroundColor: (0, _rng.withAlpha)(band.color, band.alpha)
|
|
148
|
+
}
|
|
149
|
+
}, key));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
153
|
+
style: [{
|
|
154
|
+
position: "absolute",
|
|
155
|
+
left: 0,
|
|
156
|
+
top: 0,
|
|
157
|
+
width: width * 2,
|
|
158
|
+
height
|
|
159
|
+
}, {
|
|
160
|
+
transform: [{
|
|
161
|
+
translateX
|
|
162
|
+
}]
|
|
163
|
+
}],
|
|
164
|
+
pointerEvents: "none",
|
|
165
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.RasterLayer, {
|
|
166
|
+
style: {
|
|
167
|
+
width: width * 2,
|
|
168
|
+
height
|
|
169
|
+
},
|
|
170
|
+
children: dots
|
|
171
|
+
})
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
const Starfield = exports.Starfield = /*#__PURE__*/(0, _react.memo)(function Starfield(props) {
|
|
175
|
+
// A single slow breath over the whole field. One node, and it's what stops
|
|
176
|
+
// the sky looking like a printed dot pattern now that the per-star twinkle
|
|
177
|
+
// from the Skia original isn't affordable.
|
|
178
|
+
const shimmer = (0, _primitives.usePulse)(5200, props.animated);
|
|
179
|
+
const opacity = shimmer.interpolate({
|
|
180
|
+
inputRange: [0, 1],
|
|
181
|
+
outputRange: [0.82, 1]
|
|
182
|
+
});
|
|
183
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
184
|
+
style: _absoluteFill.absoluteFill,
|
|
185
|
+
pointerEvents: "none",
|
|
186
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.Base, {
|
|
187
|
+
color: "#05060A"
|
|
188
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.RadialGlow, {
|
|
189
|
+
size: props.width * 1.6,
|
|
190
|
+
color: "#1E3A8A",
|
|
191
|
+
alpha: 0.2,
|
|
192
|
+
rings: 8,
|
|
193
|
+
falloff: 2,
|
|
194
|
+
style: {
|
|
195
|
+
position: "absolute",
|
|
196
|
+
left: -props.width * 0.3,
|
|
197
|
+
top: -props.width * 0.9
|
|
198
|
+
}
|
|
199
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
200
|
+
style: [_absoluteFill.absoluteFill, {
|
|
201
|
+
opacity
|
|
202
|
+
}],
|
|
203
|
+
pointerEvents: "none",
|
|
204
|
+
children: BANDS.map((_, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(StarBand, {
|
|
205
|
+
index: i,
|
|
206
|
+
...props
|
|
207
|
+
}, i))
|
|
208
|
+
})]
|
|
209
|
+
});
|
|
210
|
+
});
|
package/lib/commonjs/ui/index.js
CHANGED
|
@@ -31,9 +31,7 @@ Object.keys(_index).forEach(function (key) {
|
|
|
31
31
|
}
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
-
var
|
|
35
|
-
var _CyberpunkSectionButton = require("./console/CyberpunkSectionButton.js");
|
|
36
|
-
var _index2 = require("./gameUI/index.js");
|
|
34
|
+
var _index2 = require("./backgrounds/index.js");
|
|
37
35
|
Object.keys(_index2).forEach(function (key) {
|
|
38
36
|
if (key === "default" || key === "__esModule") return;
|
|
39
37
|
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
@@ -44,4 +42,18 @@ Object.keys(_index2).forEach(function (key) {
|
|
|
44
42
|
return _index2[key];
|
|
45
43
|
}
|
|
46
44
|
});
|
|
45
|
+
});
|
|
46
|
+
var _toolTheme = require("./toolTheme.js");
|
|
47
|
+
var _CyberpunkSectionButton = require("./console/CyberpunkSectionButton.js");
|
|
48
|
+
var _index3 = require("./gameUI/index.js");
|
|
49
|
+
Object.keys(_index3).forEach(function (key) {
|
|
50
|
+
if (key === "default" || key === "__esModule") return;
|
|
51
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
52
|
+
if (key in exports && exports[key] === _index3[key]) return;
|
|
53
|
+
Object.defineProperty(exports, key, {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
get: function () {
|
|
56
|
+
return _index3[key];
|
|
57
|
+
}
|
|
58
|
+
});
|
|
47
59
|
});
|
package/lib/module/JsModal.js
CHANGED
|
@@ -693,6 +693,14 @@ const JsModalComponent = ({
|
|
|
693
693
|
} else {
|
|
694
694
|
// Floating mode entrance - simple fade without scale pop
|
|
695
695
|
floatingScale.setValue(1); // Set scale to 1 directly, no animation
|
|
696
|
+
// Minimizing animated the window to the dock icon's corner. Put it
|
|
697
|
+
// back where it actually lives, or reopening leaves it parked
|
|
698
|
+
// off-screen — `initialModalState` only covers the dock's restore
|
|
699
|
+
// path, and the dial opens the same tool without one.
|
|
700
|
+
floatingPosition.setValue({
|
|
701
|
+
x: currentDimensionsRef.current.left,
|
|
702
|
+
y: currentDimensionsRef.current.top
|
|
703
|
+
});
|
|
696
704
|
openAnimation = Animated.timing(visibilityProgress, {
|
|
697
705
|
toValue: 1,
|
|
698
706
|
duration: 200,
|
|
@@ -741,7 +749,7 @@ const JsModalComponent = ({
|
|
|
741
749
|
// Stopped close animation
|
|
742
750
|
}
|
|
743
751
|
};
|
|
744
|
-
}, [visible, mode, visibilityProgress, bottomSheetTranslateY, floatingScale, externalAnimatedHeight]); // Removed initialHeight to prevent animation restarts on height changes
|
|
752
|
+
}, [visible, mode, visibilityProgress, bottomSheetTranslateY, floatingScale, floatingPosition, externalAnimatedHeight]); // Removed initialHeight to prevent animation restarts on height changes
|
|
745
753
|
|
|
746
754
|
// ============================================================================
|
|
747
755
|
// OPTIMIZED PAN RESPONDER: Bottom Sheet Resize
|
|
@@ -1111,22 +1119,18 @@ const JsModalComponent = ({
|
|
|
1111
1119
|
// RENDER: Modal UI with transform-based animations
|
|
1112
1120
|
// ============================================================================
|
|
1113
1121
|
|
|
1114
|
-
// When not visible,
|
|
1115
|
-
//
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
style: styles.hiddenContainer,
|
|
1119
|
-
pointerEvents: "none",
|
|
1120
|
-
accessibilityElementsHidden: true,
|
|
1121
|
-
importantForAccessibility: "no-hide-descendants",
|
|
1122
|
-
children: children
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1122
|
+
// When not visible the SAME tree is rendered, just parked off-screen. It has
|
|
1123
|
+
// to be the same tree: React reconciles by position, so a separate "hidden"
|
|
1124
|
+
// branch would unmount and rebuild every child on each minimize AND each
|
|
1125
|
+
// restore — which is the whole cost minimizing is supposed to avoid.
|
|
1125
1126
|
|
|
1126
1127
|
// Render floating mode
|
|
1127
1128
|
if (mode === "floating") {
|
|
1128
1129
|
return /*#__PURE__*/_jsxs(Animated.View, {
|
|
1129
1130
|
nativeID: "jsmodal-root",
|
|
1131
|
+
pointerEvents: visible ? "auto" : "none",
|
|
1132
|
+
accessibilityElementsHidden: !visible,
|
|
1133
|
+
importantForAccessibility: visible ? "auto" : "no-hide-descendants",
|
|
1130
1134
|
style: [styles.floatingModal, {
|
|
1131
1135
|
width: dimensions.width,
|
|
1132
1136
|
// Use state dimensions for real-time updates
|
|
@@ -1140,7 +1144,7 @@ const JsModalComponent = ({
|
|
|
1140
1144
|
...(zIndex !== undefined && {
|
|
1141
1145
|
zIndex
|
|
1142
1146
|
})
|
|
1143
|
-
}, (isDragging || isResizing) && styles.floatingModalDragging, customStyles.container],
|
|
1147
|
+
}, (isDragging || isResizing) && styles.floatingModalDragging, customStyles.container, !visible && styles.parkedOffscreen],
|
|
1144
1148
|
children: [/*#__PURE__*/_jsx(DraggableHeader, {
|
|
1145
1149
|
position: floatingPosition,
|
|
1146
1150
|
onDragStart: handleFloatingDragStart,
|
|
@@ -1237,10 +1241,16 @@ const JsModalComponent = ({
|
|
|
1237
1241
|
|
|
1238
1242
|
// Render bottom sheet mode with proper height animation
|
|
1239
1243
|
return /*#__PURE__*/_jsx(View, {
|
|
1240
|
-
style: [
|
|
1244
|
+
style: [
|
|
1245
|
+
// Same box either way — parking it off-screen instead of resizing it
|
|
1246
|
+
// keeps the sheet's layout intact, so coming back is a translate and
|
|
1247
|
+
// not a full relayout.
|
|
1248
|
+
visible ? styles.fullScreenContainer : styles.parkedFullScreen, visible && zIndex !== undefined && {
|
|
1241
1249
|
zIndex
|
|
1242
1250
|
}],
|
|
1243
|
-
pointerEvents: "box-none",
|
|
1251
|
+
pointerEvents: visible ? "box-none" : "none",
|
|
1252
|
+
accessibilityElementsHidden: !visible,
|
|
1253
|
+
importantForAccessibility: visible ? "auto" : "no-hide-descendants",
|
|
1244
1254
|
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
1245
1255
|
nativeID: "jsmodal-root",
|
|
1246
1256
|
style: [styles.bottomSheetWrapper, {
|
|
@@ -1336,10 +1346,23 @@ const styles = StyleSheet.create({
|
|
|
1336
1346
|
shadowRadius: 12,
|
|
1337
1347
|
elevation: 20
|
|
1338
1348
|
},
|
|
1339
|
-
|
|
1349
|
+
/** Off-screen park for a minimized floating modal — same box, moved away. */
|
|
1350
|
+
parkedOffscreen: {
|
|
1351
|
+
left: -9999,
|
|
1352
|
+
top: -9999,
|
|
1353
|
+
opacity: 0
|
|
1354
|
+
},
|
|
1355
|
+
/**
|
|
1356
|
+
* Off-screen park for a minimized bottom sheet. Screen-sized on purpose:
|
|
1357
|
+
* `fullScreenContainer` is an absolute fill, and shrinking it here would
|
|
1358
|
+
* relayout the whole sheet on every minimize/restore.
|
|
1359
|
+
*/
|
|
1360
|
+
parkedFullScreen: {
|
|
1340
1361
|
position: "absolute",
|
|
1341
1362
|
left: -9999,
|
|
1342
1363
|
top: -9999,
|
|
1364
|
+
width: SCREEN.width,
|
|
1365
|
+
height: SCREEN.height,
|
|
1343
1366
|
opacity: 0
|
|
1344
1367
|
},
|
|
1345
1368
|
floatingModal: {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Says out loud that the diff below is showing a decoded value.
|
|
5
|
+
*
|
|
6
|
+
* Not decoration: the store holds a STRING, and the rows underneath show an
|
|
7
|
+
* object or an array. Without this line the viewer would be misreporting the
|
|
8
|
+
* type of what is stored — see jsonStringValue.ts.
|
|
9
|
+
*/
|
|
10
|
+
import { memo } from "react";
|
|
11
|
+
import { View, Text, StyleSheet } from "react-native";
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
export const JsonStringNotice = /*#__PURE__*/memo(function JsonStringNotice({
|
|
14
|
+
visible,
|
|
15
|
+
theme
|
|
16
|
+
}) {
|
|
17
|
+
if (!visible) return null;
|
|
18
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
19
|
+
style: [styles.container, {
|
|
20
|
+
backgroundColor: theme.summaryBackground,
|
|
21
|
+
borderTopColor: theme.borderColor
|
|
22
|
+
}],
|
|
23
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
24
|
+
style: [styles.glyph, {
|
|
25
|
+
color: theme.lineNumberText
|
|
26
|
+
}],
|
|
27
|
+
children: "{ }"
|
|
28
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
29
|
+
style: [styles.text, {
|
|
30
|
+
color: theme.lineNumberText
|
|
31
|
+
}],
|
|
32
|
+
children: "Stored as a JSON string \u2014 decoded below so the change is readable."
|
|
33
|
+
})]
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
const styles = StyleSheet.create({
|
|
37
|
+
container: {
|
|
38
|
+
flexDirection: "row",
|
|
39
|
+
alignItems: "center",
|
|
40
|
+
gap: 7,
|
|
41
|
+
borderTopWidth: StyleSheet.hairlineWidth,
|
|
42
|
+
paddingHorizontal: 10,
|
|
43
|
+
paddingVertical: 6
|
|
44
|
+
},
|
|
45
|
+
glyph: {
|
|
46
|
+
fontSize: 11,
|
|
47
|
+
fontWeight: "700"
|
|
48
|
+
},
|
|
49
|
+
text: {
|
|
50
|
+
flex: 1,
|
|
51
|
+
fontSize: 11,
|
|
52
|
+
lineHeight: 14
|
|
53
|
+
}
|
|
54
|
+
});
|
|
@@ -14,6 +14,10 @@ import { Fragment, memo, useCallback, useEffect, useMemo, useRef, useState } fro
|
|
|
14
14
|
import { View, Text, FlatList, StyleSheet, TouchableOpacity } from "react-native";
|
|
15
15
|
import { computeLineDiff, DiffType } from "./lineDiff.js";
|
|
16
16
|
import { DiffSummary } from "./DiffSummary.js";
|
|
17
|
+
import { TimestampDeltaBar } from "./TimestampDeltaBar.js";
|
|
18
|
+
import { describeTimestampDeltas } from "./timestampDiff.js";
|
|
19
|
+
import { JsonStringNotice } from "./JsonStringNotice.js";
|
|
20
|
+
import { decodeJsonStringPair } from "./jsonStringValue.js";
|
|
17
21
|
|
|
18
22
|
/** Rendering options (the shape storage's DiffOptionsPanel edits). */
|
|
19
23
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -42,7 +46,12 @@ export function ThemedSplitView({
|
|
|
42
46
|
showDiffOnly: options.showDiffOnly,
|
|
43
47
|
contextLines: options.contextLines
|
|
44
48
|
}), [options.compareMethod, options.disableWordDiff, options.showDiffOnly, options.contextLines]);
|
|
45
|
-
|
|
49
|
+
|
|
50
|
+
// A JSON-encoded string is diffed decoded, or its one real change reads as
|
|
51
|
+
// one unreadable escaped line. Everything downstream — the line diff, the
|
|
52
|
+
// timestamp scan — works off the decoded pair.
|
|
53
|
+
const pair = useMemo(() => decodeJsonStringPair(oldValue, newValue), [oldValue, newValue]);
|
|
54
|
+
const lineDiffs = useMemo(() => computeLineDiff(pair.left, pair.right, diffComputeOptions), [pair, diffComputeOptions]);
|
|
46
55
|
|
|
47
56
|
// One pass for the summary instead of three .filter() calls per render.
|
|
48
57
|
const summary = useMemo(() => {
|
|
@@ -59,6 +68,10 @@ export function ThemedSplitView({
|
|
|
59
68
|
};
|
|
60
69
|
}, [lineDiffs]);
|
|
61
70
|
|
|
71
|
+
// Detection walks at most one object level, but it runs on every render of
|
|
72
|
+
// a diff that may hold thousands of lines — keep it on the value identities.
|
|
73
|
+
const timestampDeltas = useMemo(() => describeTimestampDeltas(pair.left, pair.right), [pair]);
|
|
74
|
+
|
|
62
75
|
// Auto-collapse runs of unchanged lines that aren't near a change. Keeps
|
|
63
76
|
// CONTEXT_LINES on either side of every change visible (GitHub-style), folds
|
|
64
77
|
// the rest into a tappable header.
|
|
@@ -147,6 +160,12 @@ export function ThemedSplitView({
|
|
|
147
160
|
removed: summary.removed,
|
|
148
161
|
modified: summary.modified,
|
|
149
162
|
theme: theme
|
|
163
|
+
}), /*#__PURE__*/_jsx(JsonStringNotice, {
|
|
164
|
+
visible: pair.decoded,
|
|
165
|
+
theme: theme
|
|
166
|
+
}), /*#__PURE__*/_jsx(TimestampDeltaBar, {
|
|
167
|
+
deltas: timestampDeltas,
|
|
168
|
+
theme: theme
|
|
150
169
|
}), lineDiffs.length === 0 ? /*#__PURE__*/_jsx(View, {
|
|
151
170
|
style: dynamicStyles.emptyState,
|
|
152
171
|
children: /*#__PURE__*/_jsx(Text, {
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TimestampDeltaBar — reads out the timestamp pairs in a diff.
|
|
5
|
+
*
|
|
6
|
+
* Sits under the diff summary and translates `1787085897165 → 1787012175875`
|
|
7
|
+
* into "20h 29m earlier", with both instants spelled out. The raw values stay
|
|
8
|
+
* on the rows below: this annotates the diff, it never replaces it.
|
|
9
|
+
*
|
|
10
|
+
* Renders nothing when no side of the diff is confidently a timestamp — see
|
|
11
|
+
* timestampDiff.ts for how narrow "confidently" is.
|
|
12
|
+
*/
|
|
13
|
+
import { memo } from "react";
|
|
14
|
+
import { View, Text, StyleSheet } from "react-native";
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
export const TimestampDeltaBar = /*#__PURE__*/memo(function TimestampDeltaBar({
|
|
17
|
+
deltas,
|
|
18
|
+
theme
|
|
19
|
+
}) {
|
|
20
|
+
if (deltas.length === 0) return null;
|
|
21
|
+
return /*#__PURE__*/_jsx(View, {
|
|
22
|
+
style: [styles.container, {
|
|
23
|
+
backgroundColor: theme.summaryBackground,
|
|
24
|
+
borderTopColor: theme.borderColor
|
|
25
|
+
}],
|
|
26
|
+
children: deltas.map(delta => /*#__PURE__*/_jsxs(View, {
|
|
27
|
+
style: styles.row,
|
|
28
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
29
|
+
style: [styles.glyph, {
|
|
30
|
+
color: theme.summaryModifiedText
|
|
31
|
+
}],
|
|
32
|
+
children: "\u25F7"
|
|
33
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
34
|
+
style: styles.text,
|
|
35
|
+
children: [/*#__PURE__*/_jsxs(Text, {
|
|
36
|
+
style: styles.headline,
|
|
37
|
+
children: [delta.path ? /*#__PURE__*/_jsxs(Text, {
|
|
38
|
+
style: [styles.path, {
|
|
39
|
+
color: theme.lineNumberText
|
|
40
|
+
}],
|
|
41
|
+
children: [delta.path, " "]
|
|
42
|
+
}) : null, /*#__PURE__*/_jsx(Text, {
|
|
43
|
+
style: {
|
|
44
|
+
color: theme.summaryModifiedText
|
|
45
|
+
},
|
|
46
|
+
children: delta.deltaLabel
|
|
47
|
+
})]
|
|
48
|
+
}), /*#__PURE__*/_jsxs(Text, {
|
|
49
|
+
style: [styles.instants, {
|
|
50
|
+
color: theme.lineNumberText
|
|
51
|
+
}],
|
|
52
|
+
children: [delta.fromLabel, " \u2192 ", delta.toLabel]
|
|
53
|
+
})]
|
|
54
|
+
})]
|
|
55
|
+
}, delta.path ?? "__value__"))
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
const styles = StyleSheet.create({
|
|
59
|
+
container: {
|
|
60
|
+
borderTopWidth: StyleSheet.hairlineWidth,
|
|
61
|
+
paddingHorizontal: 10,
|
|
62
|
+
paddingVertical: 7,
|
|
63
|
+
gap: 6
|
|
64
|
+
},
|
|
65
|
+
row: {
|
|
66
|
+
flexDirection: "row",
|
|
67
|
+
alignItems: "flex-start",
|
|
68
|
+
gap: 7
|
|
69
|
+
},
|
|
70
|
+
glyph: {
|
|
71
|
+
fontSize: 12,
|
|
72
|
+
lineHeight: 15
|
|
73
|
+
},
|
|
74
|
+
text: {
|
|
75
|
+
flex: 1,
|
|
76
|
+
minWidth: 0
|
|
77
|
+
},
|
|
78
|
+
headline: {
|
|
79
|
+
fontSize: 12,
|
|
80
|
+
fontWeight: "600",
|
|
81
|
+
lineHeight: 15
|
|
82
|
+
},
|
|
83
|
+
path: {
|
|
84
|
+
fontWeight: "400"
|
|
85
|
+
},
|
|
86
|
+
instants: {
|
|
87
|
+
fontSize: 11,
|
|
88
|
+
marginTop: 1,
|
|
89
|
+
fontVariant: ["tabular-nums"]
|
|
90
|
+
}
|
|
91
|
+
});
|
|
@@ -33,6 +33,10 @@ export { DataTreeActionDock } from "./DataTreeActionDock.js";
|
|
|
33
33
|
// Diff viewer components
|
|
34
34
|
export { SplitDiffViewer } from "./SplitDiffViewer.js";
|
|
35
35
|
export { DiffSummary } from "./DiffSummary.js";
|
|
36
|
+
export { TimestampDeltaBar } from "./TimestampDeltaBar.js";
|
|
37
|
+
export { JsonStringNotice } from "./JsonStringNotice.js";
|
|
38
|
+
export { decodeJsonStringPair, parseJsonContainer } from "./jsonStringValue.js";
|
|
39
|
+
export { detectTimestamp, describeTimestampDeltas, formatDuration, formatInstant } from "./timestampDiff.js";
|
|
36
40
|
// Diff utilities and themes
|
|
37
41
|
export { computeLineDiff, DiffType, ABSENT_VALUE, isAbsent } from "./lineDiff.js";
|
|
38
42
|
export { diffThemes, gitClassicTheme, devToolsDefaultTheme } from "./diffThemes.js";
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* JSON-encoded string values in diffs.
|
|
5
|
+
*
|
|
6
|
+
* Every device storage backend stores STRINGS, so apps write
|
|
7
|
+
* `JSON.stringify(["pikachu"])` and the stored value is the six-character
|
|
8
|
+
* string `["pikachu"]`. Rendering that through the diff's own
|
|
9
|
+
* `JSON.stringify` escapes it a second time and you get `"[\"pikachu\"]"` on
|
|
10
|
+
* one unreadable line — and a real change (one entry added to a list of
|
|
11
|
+
* twenty) becomes a single modified line you can't read.
|
|
12
|
+
*
|
|
13
|
+
* So: when a side is a JSON-encoded OBJECT OR ARRAY, diff the decoded value
|
|
14
|
+
* and say so on screen. The label is the whole contract — the store really
|
|
15
|
+
* does hold a string, and a viewer that quietly showed an array without
|
|
16
|
+
* mentioning it would be lying about the shape of the data.
|
|
17
|
+
*
|
|
18
|
+
* Scalars are deliberately NOT decoded. Turning the stored string `"5"` into
|
|
19
|
+
* the number 5, or `"true"` into a boolean, changes the apparent type while
|
|
20
|
+
* adding no readability — the exact misrepresentation this is trying to
|
|
21
|
+
* avoid.
|
|
22
|
+
*/
|
|
23
|
+
import { isAbsent } from "./lineDiff.js";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Parse a string that encodes a JSON object or array. Returns a wrapper so a
|
|
27
|
+
* successfully decoded `null`-ish payload is still distinguishable from "not
|
|
28
|
+
* decodable" (the prefix check makes that unreachable today, but callers
|
|
29
|
+
* shouldn't have to know that).
|
|
30
|
+
*/
|
|
31
|
+
export function parseJsonContainer(value) {
|
|
32
|
+
if (typeof value !== "string") return null;
|
|
33
|
+
const trimmed = value.trim();
|
|
34
|
+
// Cheap gate before JSON.parse: only containers qualify, and this keeps a
|
|
35
|
+
// try/catch off the path for every ordinary string in a diff.
|
|
36
|
+
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(trimmed);
|
|
39
|
+
if (typeof parsed !== "object" || parsed === null) return null;
|
|
40
|
+
return {
|
|
41
|
+
value: parsed
|
|
42
|
+
};
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** A side that carries no value at all — an add or a delete, not a change. */
|
|
48
|
+
function isMissing(value) {
|
|
49
|
+
return isAbsent(value) || value === undefined || value === null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Decode both sides of a diff when they are JSON-encoded containers.
|
|
54
|
+
*
|
|
55
|
+
* One side alone is decoded ONLY when the other side is missing entirely
|
|
56
|
+
* (a key being added or removed). A JSON string on one side and an ordinary
|
|
57
|
+
* value on the other is a change of shape, and decoding just one half would
|
|
58
|
+
* present it as something it isn't.
|
|
59
|
+
*/
|
|
60
|
+
export function decodeJsonStringPair(left, right) {
|
|
61
|
+
const decodedLeft = parseJsonContainer(left);
|
|
62
|
+
const decodedRight = parseJsonContainer(right);
|
|
63
|
+
if (decodedLeft && decodedRight) {
|
|
64
|
+
return {
|
|
65
|
+
left: decodedLeft.value,
|
|
66
|
+
right: decodedRight.value,
|
|
67
|
+
decoded: true
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (decodedLeft && isMissing(right)) {
|
|
71
|
+
return {
|
|
72
|
+
left: decodedLeft.value,
|
|
73
|
+
right,
|
|
74
|
+
decoded: true
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (decodedRight && isMissing(left)) {
|
|
78
|
+
return {
|
|
79
|
+
left,
|
|
80
|
+
right: decodedRight.value,
|
|
81
|
+
decoded: true
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
left,
|
|
86
|
+
right,
|
|
87
|
+
decoded: false
|
|
88
|
+
};
|
|
89
|
+
}
|