url-safe-bitpacking 0.2.1 → 0.3.1
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/README.md +20 -60
- package/dist/enums/dataTypes.d.ts +16 -4
- package/dist/factory/arrayFactory.d.ts +3 -2
- package/dist/factory/booleanFactory.d.ts +2 -1
- package/dist/factory/enumArrayFactory.d.ts +3 -2
- package/dist/factory/enumFactory.d.ts +2 -1
- package/dist/factory/enumOptionsFactory.d.ts +3 -2
- package/dist/factory/factory.d.ts +14 -10
- package/dist/factory/floatFactory.d.ts +2 -2
- package/dist/factory/intFactory.d.ts +2 -1
- package/dist/factory/objectFactory.d.ts +3 -0
- package/dist/factory/optionalFactory.d.ts +3 -2
- package/dist/factory/utils.d.ts +1 -1
- package/dist/factory/versionFactory.d.ts +2 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +767 -532
- package/dist/parsers/arrayParser.d.ts +4 -3
- package/dist/parsers/enumArrayParser.d.ts +3 -1
- package/dist/parsers/enumOptionsParser.d.ts +5 -0
- package/dist/parsers/index.d.ts +1 -0
- package/dist/parsers/intParser.d.ts +2 -4
- package/dist/parsers/objectParser.d.ts +4 -0
- package/dist/parsers/optionalParser.d.ts +4 -3
- package/dist/parsers/parserNestedDataUtils.d.ts +14 -0
- package/dist/parsers/parserUtils.d.ts +56 -0
- package/dist/parsers/parsers.d.ts +14 -80
- package/dist/stateHandling/index.d.ts +2 -1
- package/dist/stateHandling/stateData.d.ts +2 -3
- package/dist/stateHandling/stateNode.d.ts +123 -0
- package/dist/typeFactory/dataEntryTyping.d.ts +2 -2
- package/dist/types/arrayData.d.ts +3 -3
- package/dist/types/dataEntry.d.ts +45 -15
- package/dist/types/enumArrayData.d.ts +2 -0
- package/dist/types/enumData.d.ts +1 -1
- package/dist/types/enumOptionsData.d.ts +5 -3
- package/dist/types/index.d.ts +3 -1
- package/dist/types/objectData.d.ts +8 -0
- package/dist/types/optionalData.d.ts +4 -3
- package/dist/types/stateData.d.ts +4 -0
- package/dist/types/stateDataEntry.d.ts +10 -6
- package/dist/types/updateType.d.ts +16 -0
- package/dist/update/arrayUpdate.d.ts +4 -2
- package/dist/update/booleanUpdate.d.ts +3 -2
- package/dist/update/enumArrayUpdate.d.ts +3 -2
- package/dist/update/enumOptionsUpdate.d.ts +3 -2
- package/dist/update/enumUpdate.d.ts +2 -1
- package/dist/update/floatUpdate.d.ts +2 -1
- package/dist/update/index.d.ts +1 -0
- package/dist/update/intUpdate.d.ts +2 -1
- package/dist/update/objectUpdate.d.ts +2 -0
- package/dist/update/optionalUpdate.d.ts +3 -2
- package/dist/update/updateUtils.d.ts +27 -0
- package/dist/update/updateValues.d.ts +5 -4
- package/dist/update/validateUtils.d.ts +2 -0
- package/dist/update/versionUpdate.d.ts +3 -2
- package/dist/utils/interpolateData.d.ts +4 -1
- package/dist/utils/relativeValue.d.ts +4 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// src/enums/dataTypes.ts
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
var SignificandMaxBits = 20;
|
|
2
|
+
var ConstantBitWidthDataTypes = ["VERSION", "BOOLEAN", "ENUM", "INT", "FLOAT"];
|
|
3
|
+
var VariableBitWidthDataTypes = ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY", "OBJECT"];
|
|
4
|
+
var HasStateBitsDataTypes = ["ENUM_ARRAY", "OPTIONAL", "ENUM_OPTIONS", "ARRAY"];
|
|
6
5
|
// src/types/enumData.ts
|
|
7
6
|
var EnumMaxBits = 8;
|
|
7
|
+
// src/types/floatData.ts
|
|
8
|
+
var SignificandMaxBits = 20;
|
|
8
9
|
// src/types/intData.ts
|
|
9
10
|
var IntegerMaxBits = 12;
|
|
10
11
|
// src/types/dataEntry.ts
|
|
@@ -26,240 +27,64 @@ var PROTECTED_ATTRIBUTE_NAMES = [
|
|
|
26
27
|
"descriptor",
|
|
27
28
|
"mapping"
|
|
28
29
|
];
|
|
29
|
-
// src/
|
|
30
|
-
var
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const roundedMax = Math.ceil(max * precisionMultiplier);
|
|
43
|
-
const delta = roundedMax - roundedMin;
|
|
44
|
-
const significand = Math.max(1, getBitsForIntegerNumber(delta, SignificandMaxBits));
|
|
45
|
-
return {
|
|
46
|
-
value,
|
|
47
|
-
type: "FLOAT",
|
|
48
|
-
min: roundedMin / precisionMultiplier,
|
|
49
|
-
max: roundedMax / precisionMultiplier,
|
|
50
|
-
precision,
|
|
51
|
-
significand,
|
|
52
|
-
name,
|
|
53
|
-
index
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// src/factory/intFactory.ts
|
|
58
|
-
var create2 = (value, min = 0, max = 10, name = "", index = -1) => {
|
|
59
|
-
if (!Number.isInteger(min) || !Number.isInteger(max))
|
|
60
|
-
throw new Error("min and max must be integers");
|
|
61
|
-
if (max - min < 1)
|
|
62
|
-
throw new Error("max must be at least one");
|
|
63
|
-
if (Math.abs(max - min) > 2 ** IntegerMaxBits - 1)
|
|
64
|
-
throw new Error("max - min must be less than 1024");
|
|
65
|
-
const bits = getBitsForIntegerNumber(max - min + 1, IntegerMaxBits);
|
|
66
|
-
return { value, type: "INT", min, max, bits, name, index };
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
// src/factory/booleanFactory.ts
|
|
70
|
-
var create3 = (value, name = "", index = -1) => ({
|
|
71
|
-
value,
|
|
72
|
-
type: "BOOLEAN",
|
|
73
|
-
name,
|
|
74
|
-
index
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
// src/factory/versionFactory.ts
|
|
78
|
-
var create4 = (value, bits = 8, name = "", index = -1) => ({
|
|
79
|
-
value,
|
|
80
|
-
type: "VERSION",
|
|
81
|
-
bits,
|
|
82
|
-
name,
|
|
83
|
-
index
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
// src/factory/utils.ts
|
|
87
|
-
var getEnumMaxAndMappingFromOptions = (options) => {
|
|
88
|
-
if (typeof options === "string")
|
|
89
|
-
return { max: options.length - 1, mapping: options.split("") };
|
|
90
|
-
if (typeof options === "number")
|
|
91
|
-
return { max: options, mapping: Array.from({ length: options + 1 }, (_, i) => i) };
|
|
92
|
-
return { max: options.length - 1, mapping: options };
|
|
93
|
-
};
|
|
94
|
-
var getOptionsFromMaxAndMapping = (v) => {
|
|
95
|
-
if (v.mapping.every((option) => typeof option === "string" && option.length === 1))
|
|
96
|
-
return v.mapping.join("");
|
|
97
|
-
if (Array.from({ length: v.max + 1 }, (_, i) => i).every((option, i) => option === v.mapping[i]))
|
|
98
|
-
return v.max;
|
|
99
|
-
return v.mapping;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// src/factory/enumFactory.ts
|
|
103
|
-
var create5 = (value, options, name = "", index = -1) => {
|
|
104
|
-
const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
|
|
105
|
-
if (!Number.isInteger(max))
|
|
106
|
-
throw new Error(`max must be integers, you have given ${max}`);
|
|
107
|
-
if (max < 1)
|
|
108
|
-
throw new Error("max must be at least one");
|
|
109
|
-
if (max > 2 ** EnumMaxBits - 1)
|
|
110
|
-
throw new Error("max - min must be less than 256");
|
|
111
|
-
const bits = getBitsForIntegerNumber(max + 1, EnumMaxBits);
|
|
112
|
-
return { value, type: "ENUM", max, bits, name, index, mapping };
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// src/factory/enumArrayFactory.ts
|
|
116
|
-
var create6 = (value, options, minCount = 1, maxCount = 10, name = "", index = -1) => {
|
|
117
|
-
const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
|
|
118
|
-
if (!Number.isInteger(max))
|
|
119
|
-
throw new Error(`max must be integers, you have given ${max}`);
|
|
120
|
-
if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
|
|
121
|
-
throw new Error("minCount and maxCount must be integers");
|
|
122
|
-
if (max < 1)
|
|
123
|
-
throw new Error("must have at least two options");
|
|
124
|
-
if (max > 2 ** IntegerMaxBits - 1)
|
|
125
|
-
throw new Error(`maximum allowed options is 1024, you have given ${max + 1} options`);
|
|
126
|
-
minCount = Math.min(minCount, maxCount);
|
|
127
|
-
maxCount = Math.max(minCount, maxCount);
|
|
128
|
-
if (minCount < 1)
|
|
129
|
-
throw new Error("minCount must be at least one");
|
|
130
|
-
if (maxCount - minCount < 0)
|
|
131
|
-
throw new Error(`count range length must be positive, given count range length is ${Math.abs(maxCount - minCount)}`);
|
|
132
|
-
if (Math.abs(maxCount - minCount) > 2 ** IntegerMaxBits - 1)
|
|
133
|
-
throw new Error(`count range length must be less than 1024, given count range length is ${Math.abs(maxCount - minCount)}`);
|
|
134
|
-
value.forEach((v, i) => {
|
|
135
|
-
if (!Number.isInteger(v))
|
|
136
|
-
throw new Error(`all entries must be integers, index ${i} (${v}) is not`);
|
|
137
|
-
if (v > max)
|
|
138
|
-
throw new Error(`all entries must be within the range ${0} - ${max}, index ${i} (${v}) is not`);
|
|
139
|
-
});
|
|
140
|
-
if (value.length < minCount || value.length > maxCount)
|
|
141
|
-
throw new Error(`value length must be between minCount and maxCount, ${value.length} is not between ${minCount} and ${maxCount}`);
|
|
142
|
-
return {
|
|
143
|
-
type: "ENUM_ARRAY",
|
|
144
|
-
minCount,
|
|
145
|
-
maxCount,
|
|
146
|
-
value: JSON.parse(JSON.stringify(value)),
|
|
147
|
-
max,
|
|
148
|
-
name,
|
|
149
|
-
index,
|
|
150
|
-
mapping
|
|
151
|
-
};
|
|
30
|
+
// src/types/updateType.ts
|
|
31
|
+
var ComplexDataTypes = ["ENUM_OPTIONS", "OPTIONAL", "ARRAY"];
|
|
32
|
+
// src/parsers/parserUtils.ts
|
|
33
|
+
var base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
34
|
+
var getBitsForEnumArrayCountOfBase = (count, base) => Math.ceil(Math.log2(base) * count);
|
|
35
|
+
var convertArbitraryBaseToBitString = (input, fromBase) => {
|
|
36
|
+
const expectedOutputLength = getBitsForEnumArrayCountOfBase(input.length, fromBase);
|
|
37
|
+
const fromBaseBigInt = BigInt(fromBase);
|
|
38
|
+
let decimalValue = BigInt(0);
|
|
39
|
+
for (let i = input.length - 1;i >= 0; i--)
|
|
40
|
+
decimalValue = decimalValue * fromBaseBigInt + BigInt(input[i]);
|
|
41
|
+
const s = decimalValue.toString(2).padStart(expectedOutputLength, "0");
|
|
42
|
+
return s;
|
|
152
43
|
};
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
index
|
|
167
|
-
};
|
|
44
|
+
var convertBitStringToArbitraryBase = (input, toBase, expectedOutputLength) => {
|
|
45
|
+
let decimalValue = BigInt(`0b${input}`);
|
|
46
|
+
const toBaseBigInt = BigInt(toBase);
|
|
47
|
+
const result = [];
|
|
48
|
+
while (decimalValue > 0) {
|
|
49
|
+
const remainder = decimalValue % toBaseBigInt;
|
|
50
|
+
result.push(Number(remainder));
|
|
51
|
+
decimalValue = decimalValue / toBaseBigInt;
|
|
52
|
+
}
|
|
53
|
+
if (expectedOutputLength !== undefined && result.length !== expectedOutputLength)
|
|
54
|
+
for (let i = result.length;i < expectedOutputLength; i++)
|
|
55
|
+
result.push(0);
|
|
56
|
+
return result;
|
|
168
57
|
};
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
var create8 = (descriptor, defaultState = 0, name = "", index = -1) => {
|
|
174
|
-
if (descriptor.length < 2)
|
|
175
|
-
throw new Error("descriptor must have at least two entries");
|
|
176
|
-
if (descriptor.length - 1 < defaultState)
|
|
177
|
-
throw new Error("defaultState must be less than the length of the descriptor");
|
|
178
|
-
return {
|
|
179
|
-
value: JSON.parse(JSON.stringify(descriptor[defaultState])),
|
|
180
|
-
descriptor,
|
|
181
|
-
name,
|
|
182
|
-
index,
|
|
183
|
-
type: "ENUM_OPTIONS",
|
|
184
|
-
stateBits: getBitsForIntegerNumber(descriptor.length, maxEnumOptionsBits),
|
|
185
|
-
state: defaultState
|
|
186
|
-
};
|
|
58
|
+
var parseBitsToBase64 = (bits) => {
|
|
59
|
+
const chunks = bits.match(/.{1,6}/g);
|
|
60
|
+
const numbers = chunks?.map((c) => Number.parseInt(c.padEnd(6, "0"), 2)) ?? [];
|
|
61
|
+
return numbers.map((n) => base64url.charAt(n)).join("");
|
|
187
62
|
};
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
|
|
193
|
-
throw new Error("minCount and maxCount must be integers");
|
|
194
|
-
if (minCount < 0)
|
|
195
|
-
throw new Error("minCount must be at least 0");
|
|
196
|
-
if (maxCount < 0)
|
|
197
|
-
throw new Error("maxCount must be at least 0");
|
|
198
|
-
if (maxCount - minCount < 0)
|
|
199
|
-
throw new Error("maxCount must be greater than or equal to minCount");
|
|
200
|
-
if (maxCount - minCount > maxArrayCount)
|
|
201
|
-
throw new Error(`maxCount (${maxCount}) - minCount (${minCount}) = ${maxCount - minCount} must be less than or equal to maxArrayCount (${maxArrayCount})`);
|
|
202
|
-
if (defaultState < minCount || defaultState > maxCount)
|
|
203
|
-
throw new Error(`defaultState must be between minCount (${minCount}) and maxCount (${maxCount}), given defaultState is ${defaultState}`);
|
|
204
|
-
const stateBits = getMinimumBitsForInteger(maxCount - minCount);
|
|
205
|
-
return {
|
|
206
|
-
value: [...Array(defaultState)].map(() => JSON.parse(JSON.stringify(descriptor))),
|
|
207
|
-
descriptor,
|
|
208
|
-
type: "ARRAY",
|
|
209
|
-
minCount,
|
|
210
|
-
maxCount,
|
|
211
|
-
stateBits,
|
|
212
|
-
state: defaultState,
|
|
213
|
-
name,
|
|
214
|
-
index
|
|
215
|
-
};
|
|
63
|
+
var parseBase64ToBits = (base64) => {
|
|
64
|
+
const numbers = base64.split("").map((c) => base64url.indexOf(c));
|
|
65
|
+
const chunks = numbers.map((n) => n.toString(2).padStart(6, "0"));
|
|
66
|
+
return chunks.join("");
|
|
216
67
|
};
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
INT: create2,
|
|
222
|
-
ENUM: create5,
|
|
223
|
-
BOOLEAN: create3,
|
|
224
|
-
VERSION: create4,
|
|
225
|
-
ENUM_ARRAY: create6,
|
|
226
|
-
OPTIONAL: create7,
|
|
227
|
-
ENUM_OPTIONS: create8,
|
|
228
|
-
ARRAY: create9
|
|
68
|
+
var rawIntStringifier = (value, bitCount) => {
|
|
69
|
+
if (Number.isInteger(value) === false)
|
|
70
|
+
throw new Error("Value is not an integer");
|
|
71
|
+
return value.toString(2).padStart(bitCount, "0");
|
|
229
72
|
};
|
|
230
|
-
// src/parsers/intParser.ts
|
|
231
|
-
var getBitsCount = (intData2) => intData2.bits;
|
|
232
73
|
var rawValueParser = (stateString, bitCount) => {
|
|
233
74
|
if (stateString.length < bitCount)
|
|
234
75
|
throw new Error(`To few bits for this int bit string (${stateString.length} instead of ${bitCount})`);
|
|
235
76
|
if (stateString.length > bitCount)
|
|
236
77
|
throw new Error(`To many bits for this int bit string (${stateString.length} instead of ${bitCount})`);
|
|
78
|
+
if (bitCount === 0)
|
|
79
|
+
return 0;
|
|
237
80
|
const parsed = parseInt(stateString, 2);
|
|
238
81
|
if (isNaN(parsed))
|
|
239
82
|
throw new Error("Invalid int state string");
|
|
240
83
|
return parsed;
|
|
241
84
|
};
|
|
242
|
-
var rawParser = (stateString, intData2) => {
|
|
243
|
-
const v = rawValueParser(stateString, intData2.bits) + intData2.min;
|
|
244
|
-
if (v > intData2.max)
|
|
245
|
-
throw new Error("Value exceeds max");
|
|
246
|
-
return v;
|
|
247
|
-
};
|
|
248
|
-
var rawIntStringifier = (value, bitCount) => {
|
|
249
|
-
if (Number.isInteger(value) === false)
|
|
250
|
-
throw new Error("Value is not an integer");
|
|
251
|
-
return value.toString(2).padStart(bitCount, "0");
|
|
252
|
-
};
|
|
253
|
-
var rawStringifier = (value, intData2) => {
|
|
254
|
-
if (value < intData2.min)
|
|
255
|
-
throw new Error("Value is below min");
|
|
256
|
-
if (value > intData2.max)
|
|
257
|
-
throw new Error("Value exceeds max");
|
|
258
|
-
return rawIntStringifier(value - intData2.min, intData2.bits);
|
|
259
|
-
};
|
|
260
85
|
|
|
261
86
|
// src/parsers/floatParser.ts
|
|
262
|
-
var
|
|
87
|
+
var getBitsCount = (floatData2) => floatData2.significand;
|
|
263
88
|
var rawValueParser2 = (stateString, significandBits, precision) => {
|
|
264
89
|
if (stateString.length < significandBits)
|
|
265
90
|
throw new Error(`To few bits for this float bit string (${stateString.length} instead of ${significandBits})`);
|
|
@@ -268,13 +93,29 @@ var rawValueParser2 = (stateString, significandBits, precision) => {
|
|
|
268
93
|
const significand = rawValueParser(stateString, significandBits);
|
|
269
94
|
return significand * 10 ** -precision;
|
|
270
95
|
};
|
|
271
|
-
var
|
|
96
|
+
var rawParser = (stateString, floatData2) => {
|
|
272
97
|
const v = floatData2.min + rawValueParser2(stateString, floatData2.significand, floatData2.precision);
|
|
273
98
|
if (v > floatData2.max)
|
|
274
99
|
throw new Error("Float value exceeds max");
|
|
275
100
|
return v;
|
|
276
101
|
};
|
|
277
|
-
var
|
|
102
|
+
var rawStringifier = (value, floatData2) => rawIntStringifier(Math.round((value - floatData2.min) * 10 ** floatData2.precision), floatData2.significand);
|
|
103
|
+
|
|
104
|
+
// src/parsers/intParser.ts
|
|
105
|
+
var getBitsCount2 = (intData2) => intData2.bits;
|
|
106
|
+
var rawParser2 = (stateString, intData2) => {
|
|
107
|
+
const v = rawValueParser(stateString, intData2.bits) + intData2.min;
|
|
108
|
+
if (v > intData2.max)
|
|
109
|
+
throw new Error("Value exceeds max");
|
|
110
|
+
return v;
|
|
111
|
+
};
|
|
112
|
+
var rawStringifier2 = (value, intData2) => {
|
|
113
|
+
if (value < intData2.min)
|
|
114
|
+
throw new Error("Value is below min");
|
|
115
|
+
if (value > intData2.max)
|
|
116
|
+
throw new Error("Value exceeds max");
|
|
117
|
+
return rawIntStringifier(value - intData2.min, intData2.bits);
|
|
118
|
+
};
|
|
278
119
|
|
|
279
120
|
// src/parsers/enumParser.ts
|
|
280
121
|
var getBitsCount3 = (versionData2) => versionData2.bits;
|
|
@@ -307,310 +148,270 @@ var rawParser5 = (stateString) => rawValueParser3(stateString);
|
|
|
307
148
|
var rawStringifier5 = (value) => value ? "1" : "0";
|
|
308
149
|
|
|
309
150
|
// src/parsers/enumArrayParser.ts
|
|
310
|
-
var getCountBitsCount = (enumArrayData2) => getBitsForIntegerNumber(enumArrayData2.maxCount - enumArrayData2.minCount + 1, IntegerMaxBits);
|
|
311
151
|
var getNumberBitsCountForBase = (count, base) => getBitsForEnumArrayCountOfBase(count, base);
|
|
312
152
|
var getEnumArrayBase = (enumArrayData2) => enumArrayData2.max + 1;
|
|
313
|
-
var getCount = (enumArrayData2, bitString) =>
|
|
314
|
-
|
|
315
|
-
if (countBits === 0)
|
|
316
|
-
return enumArrayData2.minCount;
|
|
317
|
-
return rawValueParser(bitString.slice(0, countBits), countBits) + enumArrayData2.minCount;
|
|
318
|
-
};
|
|
319
|
-
var getBitsCount6 = (enumArrayData2, bitString) => {
|
|
320
|
-
const countBits = getCountBitsCount(enumArrayData2);
|
|
321
|
-
const count = getCount(enumArrayData2, bitString);
|
|
322
|
-
const valuesBitCount = getNumberBitsCountForBase(count, getEnumArrayBase(enumArrayData2));
|
|
323
|
-
return countBits + valuesBitCount;
|
|
324
|
-
};
|
|
325
|
-
var rawParser6 = (bitString, enumArrayData2) => {
|
|
326
|
-
const countBits = getCountBitsCount(enumArrayData2);
|
|
153
|
+
var getCount = (enumArrayData2, bitString) => rawValueParser(bitString.slice(0, enumArrayData2.stateBits), enumArrayData2.stateBits) + enumArrayData2.minCount;
|
|
154
|
+
var rawParser6 = (enumArrayData2, bitString) => {
|
|
327
155
|
const count = getCount(enumArrayData2, bitString);
|
|
328
156
|
const base = getEnumArrayBase(enumArrayData2);
|
|
329
157
|
const valuesBitCount = getNumberBitsCountForBase(count, base);
|
|
330
|
-
|
|
158
|
+
const value = convertBitStringToArbitraryBase(bitString.slice(enumArrayData2.stateBits, enumArrayData2.stateBits + valuesBitCount), base, count);
|
|
159
|
+
return [{ ...enumArrayData2, value }, bitString.slice(enumArrayData2.stateBits + valuesBitCount)];
|
|
331
160
|
};
|
|
161
|
+
var rawStateStringifier = (value, minCount, stateBits) => stateBits ? rawIntStringifier(value.length - minCount, stateBits) : "";
|
|
332
162
|
var rawStringifier6 = (value, enumArrayData2) => {
|
|
333
|
-
const
|
|
334
|
-
const count = value.length;
|
|
163
|
+
const countBitstring = rawStateStringifier(value, enumArrayData2.minCount, enumArrayData2.stateBits);
|
|
335
164
|
const base = getEnumArrayBase(enumArrayData2);
|
|
336
|
-
const countBitstring = countBits ? rawIntStringifier(count - enumArrayData2.minCount, countBits) : "";
|
|
337
165
|
const enumArrayBitstring = convertArbitraryBaseToBitString(value, base);
|
|
338
166
|
return countBitstring + enumArrayBitstring;
|
|
339
167
|
};
|
|
340
168
|
|
|
169
|
+
// src/parsers/parserNestedDataUtils.ts
|
|
170
|
+
var nestedDataStringifier = (nestedData) => nestedData.map(dataEntryBitsStringifier).join("");
|
|
171
|
+
var nestedDataBitstringParser = (bitstring, descriptor) => {
|
|
172
|
+
const resultingNestedData = descriptor.map((data) => {
|
|
173
|
+
const [resultingData, remainingBitstring] = dataEntryBitstringParser(data, bitstring);
|
|
174
|
+
bitstring = remainingBitstring;
|
|
175
|
+
return resultingData;
|
|
176
|
+
});
|
|
177
|
+
return [resultingNestedData, bitstring];
|
|
178
|
+
};
|
|
179
|
+
|
|
341
180
|
// src/parsers/arrayParser.ts
|
|
342
181
|
var getCount2 = (arrayData2, bitString) => {
|
|
343
182
|
if (arrayData2.stateBits === 0)
|
|
344
183
|
return arrayData2.minCount;
|
|
345
184
|
return rawValueParser(bitString.slice(0, arrayData2.stateBits), arrayData2.stateBits) + arrayData2.minCount;
|
|
346
185
|
};
|
|
347
|
-
var rawParser7 = (
|
|
186
|
+
var rawParser7 = (arrayData2, bitString) => {
|
|
348
187
|
const state = getCount2(arrayData2, bitString);
|
|
349
188
|
bitString = bitString.slice(arrayData2.stateBits);
|
|
350
189
|
const value = [];
|
|
351
190
|
for (let i = 0;i < state; i++) {
|
|
352
|
-
const [
|
|
353
|
-
value.push(
|
|
191
|
+
const [entry, remainingBitstring] = dataEntryBitstringParser(arrayData2.descriptor, bitString);
|
|
192
|
+
value.push(entry);
|
|
354
193
|
bitString = remainingBitstring;
|
|
355
194
|
}
|
|
356
195
|
return [{ ...arrayData2, value, state }, bitString];
|
|
357
196
|
};
|
|
358
|
-
var
|
|
197
|
+
var rawStateStringifier2 = (state, minCount, stateBits) => stateBits ? rawIntStringifier(state - minCount, stateBits) : "";
|
|
359
198
|
var rawStringifier7 = (arrayData2) => {
|
|
360
|
-
return
|
|
199
|
+
return rawStateStringifier2(arrayData2.state, arrayData2.minCount, arrayData2.stateBits) + nestedDataStringifier(arrayData2.value);
|
|
361
200
|
};
|
|
362
201
|
|
|
363
202
|
// src/parsers/optionalParser.ts
|
|
364
203
|
var getState = (bitString) => Number(bitString.slice(0, 1));
|
|
365
|
-
var rawParser8 = (
|
|
204
|
+
var rawParser8 = (optionalData2, bitString) => {
|
|
366
205
|
const descriptorIndex = getState(bitString);
|
|
367
|
-
bitString = bitString.slice(
|
|
368
|
-
const [value, remainingBitstring] = optionalData2.descriptor[descriptorIndex] ?
|
|
206
|
+
bitString = bitString.slice(optionalData2.stateBits);
|
|
207
|
+
const [value, remainingBitstring] = optionalData2.descriptor[descriptorIndex] ? dataEntryBitstringParser(optionalData2.descriptor[descriptorIndex], bitString) : [null, bitString];
|
|
369
208
|
const state = Boolean(descriptorIndex);
|
|
370
209
|
return [{ ...optionalData2, value, state }, remainingBitstring];
|
|
371
210
|
};
|
|
372
|
-
var
|
|
373
|
-
var rawStringifier8 = (optionalData2) => optionalData2.value === null ?
|
|
211
|
+
var rawStateStringifier3 = (state) => state ? "1" : "0";
|
|
212
|
+
var rawStringifier8 = (optionalData2) => optionalData2.value === null ? rawStateStringifier3(optionalData2.state) : rawStateStringifier3(optionalData2.state) + dataEntryBitsStringifier(optionalData2.value);
|
|
374
213
|
|
|
375
|
-
// src/parsers/
|
|
214
|
+
// src/parsers/enumOptionsParser.ts
|
|
376
215
|
var getStateIndex = (enumOptionsData2, bitString) => {
|
|
377
216
|
if (enumOptionsData2.stateBits === 0)
|
|
378
217
|
return 0;
|
|
379
218
|
return rawValueParser(bitString.slice(0, enumOptionsData2.stateBits), enumOptionsData2.stateBits);
|
|
380
219
|
};
|
|
381
|
-
var rawParser9 = (
|
|
220
|
+
var rawParser9 = (enumOptionsData2, bitString) => {
|
|
382
221
|
const state = getStateIndex(enumOptionsData2, bitString);
|
|
383
222
|
bitString = bitString.slice(enumOptionsData2.stateBits);
|
|
384
|
-
const [value, remainingBitstring] =
|
|
223
|
+
const [value, remainingBitstring] = enumOptionsData2.descriptor[state] ? dataEntryBitstringParser(enumOptionsData2.descriptor[state], bitString) : [null, bitString];
|
|
385
224
|
return [{ ...enumOptionsData2, value, state }, remainingBitstring];
|
|
386
225
|
};
|
|
387
|
-
var
|
|
388
|
-
var rawStringifier9 = (enumOptionsData2) =>
|
|
226
|
+
var rawStateStringifier4 = (state, stateBits) => rawIntStringifier(state, stateBits);
|
|
227
|
+
var rawStringifier9 = (enumOptionsData2) => rawStateStringifier4(enumOptionsData2.state, enumOptionsData2.stateBits) + (enumOptionsData2.value ? dataEntryBitsStringifier(enumOptionsData2.value) : "");
|
|
228
|
+
|
|
229
|
+
// src/parsers/objectParser.ts
|
|
230
|
+
var rawParser10 = (objectData2, bitString) => {
|
|
231
|
+
const [value, remainingBitstring] = nestedDataBitstringParser(bitString, objectData2.descriptor);
|
|
232
|
+
return [{ ...objectData2, value }, remainingBitstring];
|
|
233
|
+
};
|
|
234
|
+
var rawStringifier10 = (objectData2) => nestedDataStringifier(objectData2.value);
|
|
389
235
|
|
|
390
236
|
// src/parsers/parsers.ts
|
|
391
|
-
var
|
|
392
|
-
switch (
|
|
237
|
+
var simpleContentBitsCountForDataEntry = (entry) => {
|
|
238
|
+
switch (entry.type) {
|
|
393
239
|
case "BOOLEAN":
|
|
394
|
-
return
|
|
240
|
+
return getBitsCount5();
|
|
395
241
|
case "INT":
|
|
396
|
-
return
|
|
242
|
+
return getBitsCount2(entry);
|
|
397
243
|
case "ENUM":
|
|
398
|
-
return
|
|
244
|
+
return getBitsCount3(entry);
|
|
399
245
|
case "FLOAT":
|
|
400
|
-
return
|
|
246
|
+
return getBitsCount(entry);
|
|
401
247
|
case "VERSION":
|
|
402
|
-
return
|
|
403
|
-
case "ENUM_ARRAY":
|
|
404
|
-
return rawParser6(bitString, mapData);
|
|
248
|
+
return getBitsCount4(entry);
|
|
405
249
|
}
|
|
406
250
|
};
|
|
407
|
-
var
|
|
408
|
-
|
|
251
|
+
var helperSimpleParserWrapper = (entry, bitstring) => [
|
|
252
|
+
{ ...entry, value: simpleFromValueParser(bitstring.slice(0, simpleContentBitsCountForDataEntry(entry)), entry) },
|
|
253
|
+
bitstring.slice(simpleContentBitsCountForDataEntry(entry))
|
|
254
|
+
];
|
|
255
|
+
var simpleFromValueParser = (bitString, entry) => {
|
|
256
|
+
switch (entry.type) {
|
|
409
257
|
case "BOOLEAN":
|
|
410
|
-
return
|
|
258
|
+
return rawParser5(bitString);
|
|
259
|
+
case "INT":
|
|
260
|
+
return rawParser2(bitString, entry);
|
|
411
261
|
case "ENUM":
|
|
262
|
+
return rawParser3(bitString, entry);
|
|
263
|
+
case "FLOAT":
|
|
264
|
+
return rawParser(bitString, entry);
|
|
265
|
+
case "VERSION":
|
|
266
|
+
return rawParser4(bitString, entry);
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
var dataEntryBitstringParser = (entry, bitString) => {
|
|
270
|
+
const result = _dataEntryBitstringParser(entry, bitString);
|
|
271
|
+
return result;
|
|
272
|
+
};
|
|
273
|
+
var _dataEntryBitstringParser = (entry, bitString) => {
|
|
274
|
+
switch (entry.type) {
|
|
275
|
+
case "BOOLEAN":
|
|
412
276
|
case "INT":
|
|
277
|
+
case "ENUM":
|
|
413
278
|
case "FLOAT":
|
|
414
279
|
case "VERSION":
|
|
415
|
-
return
|
|
280
|
+
return helperSimpleParserWrapper(entry, bitString);
|
|
416
281
|
case "ENUM_ARRAY":
|
|
417
|
-
return
|
|
282
|
+
return rawParser6(entry, bitString);
|
|
283
|
+
case "ARRAY":
|
|
284
|
+
return rawParser7(entry, bitString);
|
|
285
|
+
case "OPTIONAL":
|
|
286
|
+
return rawParser8(entry, bitString);
|
|
287
|
+
case "ENUM_OPTIONS":
|
|
288
|
+
return rawParser9(entry, bitString);
|
|
289
|
+
case "OBJECT":
|
|
290
|
+
return rawParser10(entry, bitString);
|
|
418
291
|
}
|
|
419
292
|
};
|
|
420
|
-
var
|
|
293
|
+
var getBitsCount6 = (mapData) => {
|
|
421
294
|
switch (mapData.type) {
|
|
422
295
|
case "BOOLEAN":
|
|
423
296
|
return getBitsCount5();
|
|
424
297
|
case "INT":
|
|
425
|
-
return getBitsCount(mapData);
|
|
426
|
-
case "FLOAT":
|
|
427
298
|
return getBitsCount2(mapData);
|
|
299
|
+
case "FLOAT":
|
|
300
|
+
return getBitsCount(mapData);
|
|
428
301
|
case "VERSION":
|
|
429
302
|
return getBitsCount4(mapData);
|
|
430
303
|
case "ENUM":
|
|
431
304
|
return getBitsCount3(mapData);
|
|
432
|
-
case "ENUM_ARRAY":
|
|
433
|
-
return getBitsCount6(mapData, bitString);
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
var dataEntryBitstringParser = (bitstring, dataEntry2) => [
|
|
437
|
-
dataBitsParser(bitstring.slice(0, getBitsCount7(dataEntry2, bitstring)), dataEntry2),
|
|
438
|
-
bitstring.slice(getBitsCount7(dataEntry2, bitstring))
|
|
439
|
-
];
|
|
440
|
-
var nestedDataBitstringParser = (bitstring, descriptor) => {
|
|
441
|
-
const resultingNestedData = descriptor.map((data) => {
|
|
442
|
-
const [resultingData, remainingBitstring] = ComplexDataValues.includes(data.type) ? complexDataEntryBitstringParser(bitstring, data) : dataEntryBitstringParser(bitstring, data);
|
|
443
|
-
bitstring = remainingBitstring;
|
|
444
|
-
return resultingData;
|
|
445
|
-
});
|
|
446
|
-
return [resultingNestedData, bitstring];
|
|
447
|
-
};
|
|
448
|
-
var complexDataEntryBitstringParser = (bitstring, complexDataEntry) => {
|
|
449
|
-
switch (complexDataEntry.type) {
|
|
450
|
-
case "ARRAY":
|
|
451
|
-
return rawParser7(bitstring, complexDataEntry);
|
|
452
|
-
case "OPTIONAL":
|
|
453
|
-
return rawParser8(bitstring, complexDataEntry);
|
|
454
|
-
case "ENUM_OPTIONS":
|
|
455
|
-
return rawParser9(bitstring, complexDataEntry);
|
|
456
305
|
}
|
|
457
306
|
};
|
|
458
|
-
var
|
|
459
|
-
switch (
|
|
307
|
+
var dataEntryBitsStringifier = (entry) => {
|
|
308
|
+
switch (entry.type) {
|
|
460
309
|
case "BOOLEAN":
|
|
461
|
-
return rawStringifier5(
|
|
310
|
+
return rawStringifier5(entry.value);
|
|
462
311
|
case "INT":
|
|
463
|
-
return
|
|
312
|
+
return rawStringifier2(entry.value, entry);
|
|
464
313
|
case "FLOAT":
|
|
465
|
-
return
|
|
314
|
+
return rawStringifier(entry.value, entry);
|
|
466
315
|
case "VERSION":
|
|
467
|
-
return rawStringifier4(
|
|
316
|
+
return rawStringifier4(entry.value, entry);
|
|
468
317
|
case "ENUM":
|
|
469
|
-
return rawStringifier3(
|
|
318
|
+
return rawStringifier3(entry.value, entry);
|
|
470
319
|
case "ENUM_ARRAY":
|
|
471
|
-
return rawStringifier6(
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
var complexDataStringifier = (complexDataEntry) => {
|
|
475
|
-
switch (complexDataEntry.type) {
|
|
320
|
+
return rawStringifier6(entry.value, entry);
|
|
476
321
|
case "ARRAY":
|
|
477
|
-
return rawStringifier7(
|
|
322
|
+
return rawStringifier7(entry);
|
|
478
323
|
case "OPTIONAL":
|
|
479
|
-
return rawStringifier8(
|
|
324
|
+
return rawStringifier8(entry);
|
|
480
325
|
case "ENUM_OPTIONS":
|
|
481
|
-
return rawStringifier9(
|
|
326
|
+
return rawStringifier9(entry);
|
|
327
|
+
case "OBJECT":
|
|
328
|
+
return rawStringifier10(entry);
|
|
482
329
|
}
|
|
483
330
|
};
|
|
484
|
-
var
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
};
|
|
494
|
-
var nestedDataStringifier = (nestedData) => nestedData.map((d) => ComplexDataValues.includes(d.type) ? complexDataStringifier(d) : dataBitsStringifier(d)).join("");
|
|
495
|
-
var dataEntryCorrecting = (dataEntry2) => dataBitsParser(dataBitsStringifier(dataEntry2), dataEntry2);
|
|
496
|
-
var base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
497
|
-
var getBitsForEnumArrayCountOfBase = (count, base) => Math.ceil(Math.log2(base) * count);
|
|
498
|
-
var convertArbitraryBaseToBitString = (input, fromBase) => {
|
|
499
|
-
const expectedOutputLength = getBitsForEnumArrayCountOfBase(input.length, fromBase);
|
|
500
|
-
const fromBaseBigInt = BigInt(fromBase);
|
|
501
|
-
let decimalValue = BigInt(0);
|
|
502
|
-
for (let i = input.length - 1;i >= 0; i--)
|
|
503
|
-
decimalValue = decimalValue * fromBaseBigInt + BigInt(input[i]);
|
|
504
|
-
const s = decimalValue.toString(2).padStart(expectedOutputLength, "0");
|
|
505
|
-
return s;
|
|
506
|
-
};
|
|
507
|
-
var convertBitStringToArbitraryBase = (input, toBase, expectedOutputLength) => {
|
|
508
|
-
let decimalValue = BigInt(`0b${input}`);
|
|
509
|
-
const toBaseBigInt = BigInt(toBase);
|
|
510
|
-
const result = [];
|
|
511
|
-
while (decimalValue > 0) {
|
|
512
|
-
const remainder = decimalValue % toBaseBigInt;
|
|
513
|
-
result.push(Number(remainder));
|
|
514
|
-
decimalValue = decimalValue / toBaseBigInt;
|
|
515
|
-
}
|
|
516
|
-
if (expectedOutputLength !== undefined && result.length !== expectedOutputLength)
|
|
517
|
-
for (let i = result.length;i < expectedOutputLength; i++)
|
|
518
|
-
result.push(0);
|
|
519
|
-
return result;
|
|
520
|
-
};
|
|
521
|
-
var parseBitsToBase64 = (bits) => {
|
|
522
|
-
const chunks = bits.match(/.{1,6}/g);
|
|
523
|
-
const numbers = chunks?.map((c) => Number.parseInt(c.padEnd(6, "0"), 2)) ?? [];
|
|
524
|
-
return numbers.map((n) => base64url.charAt(n)).join("");
|
|
525
|
-
};
|
|
526
|
-
var parseBase64ToBits = (base64) => {
|
|
527
|
-
const numbers = base64.split("").map((c) => base64url.indexOf(c));
|
|
528
|
-
const chunks = numbers.map((n) => n.toString(2).padStart(6, "0"));
|
|
529
|
-
return chunks.join("");
|
|
331
|
+
var dataEntryCorrecting = (dataEntry2) => dataEntryBitstringParser(dataEntry2, dataEntryBitsStringifier(dataEntry2))[0];
|
|
332
|
+
// src/update/updateUtils.ts
|
|
333
|
+
var getStepForPrecision = (precision) => 10 ** -precision;
|
|
334
|
+
var constrainUnsignedInt = (value, maxValue) => Math.max(0, Math.min(Math.round(value), maxValue));
|
|
335
|
+
var constrainSignedInt = (value, minValue, maxValue) => constrainUnsignedInt(Math.round(value - minValue), Math.floor(maxValue - minValue)) + minValue;
|
|
336
|
+
var constrainFloat = (value, minValue, maxValue, precision) => {
|
|
337
|
+
const step = getStepForPrecision(precision);
|
|
338
|
+
const multi = 1 / step;
|
|
339
|
+
return constrainSignedInt(value * multi, minValue * multi, maxValue * multi) * step;
|
|
530
340
|
};
|
|
341
|
+
|
|
531
342
|
// src/update/floatUpdate.ts
|
|
532
|
-
var
|
|
533
|
-
|
|
534
|
-
return original;
|
|
535
|
-
};
|
|
343
|
+
var constrainValue = (original, update) => constrainFloat(update, original.min, original.max, original.precision);
|
|
344
|
+
var updateValue = (original, update) => (original.value = constrainValue(original, update), original);
|
|
536
345
|
|
|
537
346
|
// src/update/intUpdate.ts
|
|
538
|
-
var
|
|
539
|
-
|
|
540
|
-
return original;
|
|
541
|
-
};
|
|
347
|
+
var constrainValue2 = (original, update) => constrainSignedInt(update, original.min, original.max);
|
|
348
|
+
var updateValue2 = (original, update) => (original.value = constrainValue2(original, update), original);
|
|
542
349
|
|
|
543
350
|
// src/update/enumUpdate.ts
|
|
544
|
-
var
|
|
545
|
-
|
|
546
|
-
return original;
|
|
547
|
-
};
|
|
351
|
+
var constrainValue3 = (original, update) => constrainUnsignedInt(update, original.max);
|
|
352
|
+
var updateValue3 = (original, update) => (original.value = constrainValue3(original, update), original);
|
|
548
353
|
|
|
549
354
|
// src/update/versionUpdate.ts
|
|
550
|
-
var
|
|
551
|
-
|
|
552
|
-
return {
|
|
553
|
-
...original,
|
|
554
|
-
value
|
|
555
|
-
};
|
|
556
|
-
};
|
|
355
|
+
var constrainValue4 = (original, update) => constrainUnsignedInt(update, original.bits ** 2 - 1);
|
|
356
|
+
var updateValue4 = (original, update) => (original.value = constrainValue4(original, update), original);
|
|
557
357
|
|
|
558
358
|
// src/update/booleanUpdate.ts
|
|
559
|
-
var
|
|
560
|
-
|
|
561
|
-
return original;
|
|
562
|
-
};
|
|
359
|
+
var constrainValue5 = (original, update) => update === true ? true : false;
|
|
360
|
+
var updateValue5 = (original, update) => (original.value = constrainValue5(original, update), original);
|
|
563
361
|
|
|
564
362
|
// src/update/enumArrayUpdate.ts
|
|
565
|
-
var
|
|
566
|
-
const count =
|
|
567
|
-
|
|
568
|
-
return original;
|
|
363
|
+
var constrainValue6 = (original, update) => {
|
|
364
|
+
const count = constrainUnsignedInt(update.length, original.maxCount);
|
|
365
|
+
return [...new Array(count)].map((_, i) => constrainUnsignedInt(update[i] ?? 0, original.max));
|
|
569
366
|
};
|
|
367
|
+
var updateValue6 = (original, update) => (original.value = constrainValue6(original, update), original);
|
|
570
368
|
|
|
571
|
-
// src/update/
|
|
572
|
-
var
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
369
|
+
// src/update/validateUtils.ts
|
|
370
|
+
var validateDataEntry = (descriptorValue, differentValue) => {
|
|
371
|
+
if (descriptorValue === null)
|
|
372
|
+
return null;
|
|
373
|
+
if (differentValue === null)
|
|
374
|
+
return descriptorValue;
|
|
375
|
+
if (descriptorValue.type === differentValue.type)
|
|
376
|
+
if (ComplexDataTypes.includes(descriptorValue.type))
|
|
377
|
+
return updateStateEntry(descriptorValue, differentValue.state);
|
|
378
|
+
else
|
|
379
|
+
return updateValueEntry(descriptorValue, differentValue.value);
|
|
380
|
+
return descriptorValue;
|
|
577
381
|
};
|
|
578
382
|
|
|
579
383
|
// src/update/optionalUpdate.ts
|
|
580
|
-
var
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
original.value.push(...updateNestedData(update.value, original.descriptor[Number(update.state)]));
|
|
585
|
-
}
|
|
384
|
+
var constrainState = (state) => state === true ? true : false;
|
|
385
|
+
var updateState = (original, state) => {
|
|
386
|
+
original.state = constrainState(state);
|
|
387
|
+
original.value = validateDataEntry(original.descriptor[Number(state)], original.value);
|
|
586
388
|
return original;
|
|
587
389
|
};
|
|
588
390
|
|
|
589
391
|
// src/update/enumOptionsUpdate.ts
|
|
590
|
-
var
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
original.state = update.state;
|
|
595
|
-
}
|
|
392
|
+
var constrainState2 = (descriptorLength, state) => constrainUnsignedInt(state, descriptorLength - 1);
|
|
393
|
+
var updateState2 = (original, state) => {
|
|
394
|
+
original.state = constrainState2(original.descriptor.length, state);
|
|
395
|
+
original.value = validateDataEntry(original.descriptor[original.state], original.value);
|
|
596
396
|
return original;
|
|
597
397
|
};
|
|
598
398
|
|
|
599
399
|
// src/update/arrayUpdate.ts
|
|
600
|
-
var
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
400
|
+
var constrainState3 = (state, minCount, maxCount) => constrainSignedInt(state, minCount, maxCount);
|
|
401
|
+
var updateState3 = (original, state) => {
|
|
402
|
+
original.state = constrainState3(state, original.minCount, original.maxCount);
|
|
403
|
+
original.value = [...new Array(original.state)].map((_, i) => original.value[i] ? validateDataEntry(original.descriptor, original.value[i] ?? null) : original.descriptor);
|
|
404
|
+
return original;
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
// src/update/objectUpdate.ts
|
|
408
|
+
var updateValue7 = (original, value) => {
|
|
409
|
+
original.value = original.descriptor.map((v, i) => validateDataEntry(v, value[i] ?? null));
|
|
607
410
|
return original;
|
|
608
411
|
};
|
|
609
412
|
|
|
610
413
|
// src/update/updateValues.ts
|
|
611
|
-
var
|
|
612
|
-
if (original.type !== update.type)
|
|
613
|
-
throw new Error("Types do not match");
|
|
414
|
+
var updateValueEntry = (original, update) => {
|
|
614
415
|
switch (original.type) {
|
|
615
416
|
case "FLOAT":
|
|
616
417
|
return updateValue(original, update);
|
|
@@ -624,132 +425,562 @@ var updateValue7 = (original, update) => {
|
|
|
624
425
|
return updateValue4(original, update);
|
|
625
426
|
case "ENUM_ARRAY":
|
|
626
427
|
return updateValue6(original, update);
|
|
428
|
+
case "OBJECT":
|
|
429
|
+
return updateValue7(original, update);
|
|
627
430
|
}
|
|
628
431
|
};
|
|
629
|
-
var
|
|
630
|
-
|
|
631
|
-
|
|
432
|
+
var constrainValue7 = (original, update) => {
|
|
433
|
+
switch (original.type) {
|
|
434
|
+
case "FLOAT":
|
|
435
|
+
return constrainValue(original, update);
|
|
436
|
+
case "INT":
|
|
437
|
+
return constrainValue2(original, update);
|
|
438
|
+
case "ENUM":
|
|
439
|
+
return constrainValue3(original, update);
|
|
440
|
+
case "BOOLEAN":
|
|
441
|
+
return constrainValue5(original, update);
|
|
442
|
+
case "VERSION":
|
|
443
|
+
return constrainValue4(original, update);
|
|
444
|
+
case "ENUM_ARRAY":
|
|
445
|
+
return constrainValue6(original, update);
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
var updateStateEntry = (original, update) => {
|
|
632
449
|
switch (original.type) {
|
|
633
450
|
case "OPTIONAL":
|
|
634
|
-
return
|
|
451
|
+
return updateState(original, update);
|
|
635
452
|
case "ENUM_OPTIONS":
|
|
636
|
-
return
|
|
453
|
+
return updateState2(original, update);
|
|
637
454
|
case "ARRAY":
|
|
638
|
-
return
|
|
455
|
+
return updateState3(original, update);
|
|
639
456
|
}
|
|
640
457
|
};
|
|
458
|
+
// src/factory/helperMethod.ts
|
|
459
|
+
var getBitsForIntegerNumber = (number, maxBits) => {
|
|
460
|
+
const bitCount = Math.ceil(Math.log2(number));
|
|
461
|
+
if (bitCount > maxBits)
|
|
462
|
+
throw new Error(`Cannot get ${maxBits} bits for a number with ${bitCount} bits`);
|
|
463
|
+
return bitCount;
|
|
464
|
+
};
|
|
465
|
+
var getMinimumBitsForInteger = (v) => Math.ceil(Math.log2(v + 1));
|
|
466
|
+
|
|
467
|
+
// src/factory/floatFactory.ts
|
|
468
|
+
var create = (value, min = 0, max = 1, precision = 2, name = "a float") => {
|
|
469
|
+
const precisionMultiplier = 10 ** precision;
|
|
470
|
+
const roundedMin = Math.floor(min * precisionMultiplier);
|
|
471
|
+
const roundedMax = Math.ceil(max * precisionMultiplier);
|
|
472
|
+
const delta = roundedMax - roundedMin;
|
|
473
|
+
const significand = Math.max(1, getBitsForIntegerNumber(delta, SignificandMaxBits));
|
|
474
|
+
return {
|
|
475
|
+
value,
|
|
476
|
+
type: "FLOAT",
|
|
477
|
+
min: roundedMin / precisionMultiplier,
|
|
478
|
+
max: roundedMax / precisionMultiplier,
|
|
479
|
+
precision,
|
|
480
|
+
significand,
|
|
481
|
+
name
|
|
482
|
+
};
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
// src/factory/intFactory.ts
|
|
486
|
+
var create2 = (value, min = 0, max = 10, name = "an int") => {
|
|
487
|
+
if (!Number.isInteger(min) || !Number.isInteger(max))
|
|
488
|
+
throw new Error("min and max must be integers");
|
|
489
|
+
if (max - min < 1)
|
|
490
|
+
throw new Error("max must be at least one");
|
|
491
|
+
if (Math.abs(max - min) > 2 ** IntegerMaxBits - 1)
|
|
492
|
+
throw new Error("max - min must be less than 1024");
|
|
493
|
+
const bits = getBitsForIntegerNumber(max - min + 1, IntegerMaxBits);
|
|
494
|
+
return { value, type: "INT", min, max, bits, name };
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
// src/factory/booleanFactory.ts
|
|
498
|
+
var create3 = (value, name = "a boolean") => ({
|
|
499
|
+
value,
|
|
500
|
+
type: "BOOLEAN",
|
|
501
|
+
name
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
// src/factory/versionFactory.ts
|
|
505
|
+
var create4 = (value, bits = 8, name = "a version") => ({
|
|
506
|
+
value,
|
|
507
|
+
type: "VERSION",
|
|
508
|
+
bits,
|
|
509
|
+
name
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
// src/factory/utils.ts
|
|
513
|
+
var getEnumMaxAndMappingFromOptions = (options) => {
|
|
514
|
+
if (typeof options === "string")
|
|
515
|
+
return { max: options.length - 1, mapping: options.split("") };
|
|
516
|
+
if (typeof options === "number")
|
|
517
|
+
return { max: options, mapping: Array.from({ length: options + 1 }, (_, i) => i) };
|
|
518
|
+
return { max: options.length - 1, mapping: options };
|
|
519
|
+
};
|
|
520
|
+
var getOptionsFromMaxAndMapping = (v) => {
|
|
521
|
+
if (v.mapping.every((option) => typeof option === "string" && option.length === 1))
|
|
522
|
+
return v.mapping.join("");
|
|
523
|
+
if (Array.from({ length: v.max + 1 }, (_, i) => i).every((option, i) => option === v.mapping[i]))
|
|
524
|
+
return v.max;
|
|
525
|
+
return v.mapping;
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
// src/factory/enumFactory.ts
|
|
529
|
+
var create5 = (value, options, name = "an enum") => {
|
|
530
|
+
const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
|
|
531
|
+
if (!Number.isInteger(max))
|
|
532
|
+
throw new Error(`max must be integers, you have given ${max}`);
|
|
533
|
+
if (max < 1)
|
|
534
|
+
throw new Error("max must be at least one");
|
|
535
|
+
if (max > 2 ** EnumMaxBits - 1)
|
|
536
|
+
throw new Error("max - min must be less than 256");
|
|
537
|
+
const bits = getBitsForIntegerNumber(max + 1, EnumMaxBits);
|
|
538
|
+
return { value, type: "ENUM", max, bits, name, mapping };
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
// src/factory/enumArrayFactory.ts
|
|
542
|
+
var minEnumArrayCount = 0;
|
|
543
|
+
var maxOptionsCount = 1024;
|
|
544
|
+
var create6 = (value, options, minCount = minEnumArrayCount, maxCount = 10, name = "enum array") => {
|
|
545
|
+
const { max, mapping } = getEnumMaxAndMappingFromOptions(options);
|
|
546
|
+
if (!Number.isInteger(max))
|
|
547
|
+
throw new Error(`max must be integers, you have given ${max}`);
|
|
548
|
+
if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
|
|
549
|
+
throw new Error("minCount and maxCount must be integers");
|
|
550
|
+
if (max < 1)
|
|
551
|
+
throw new Error("must have at least one option");
|
|
552
|
+
if (max > maxOptionsCount)
|
|
553
|
+
throw new Error(`maximum allowed options is 1024, you have given ${max + 1} options`);
|
|
554
|
+
minCount = Math.min(minCount, maxCount);
|
|
555
|
+
maxCount = Math.max(minCount, maxCount);
|
|
556
|
+
if (minCount < 0)
|
|
557
|
+
throw new Error("minCount can't be negative");
|
|
558
|
+
if (maxCount - minCount < 0)
|
|
559
|
+
throw new Error(`count range length must be positive, given count range length is ${Math.abs(maxCount - minCount)}`);
|
|
560
|
+
if (Math.abs(maxCount - minCount) > 2 ** IntegerMaxBits - 1)
|
|
561
|
+
throw new Error(`count range length must be less than 1024, given count range length is ${Math.abs(maxCount - minCount)}`);
|
|
562
|
+
value.forEach((v, i) => {
|
|
563
|
+
if (!Number.isInteger(v))
|
|
564
|
+
throw new Error(`all entries must be integers, index ${i} (${v}) is not`);
|
|
565
|
+
if (v > max)
|
|
566
|
+
throw new Error(`all entries must be within the range ${0} - ${max}, index ${i} (${v}) is not`);
|
|
567
|
+
});
|
|
568
|
+
if (value.length < minCount || value.length > maxCount)
|
|
569
|
+
throw new Error(`value length must be between minCount and maxCount, ${value.length} is not between ${minCount} and ${maxCount}`);
|
|
570
|
+
const stateBits = getBitsForIntegerNumber(maxCount - minCount + 1, IntegerMaxBits);
|
|
571
|
+
return {
|
|
572
|
+
type: "ENUM_ARRAY",
|
|
573
|
+
minCount,
|
|
574
|
+
maxCount,
|
|
575
|
+
value: JSON.parse(JSON.stringify(value)),
|
|
576
|
+
max,
|
|
577
|
+
name,
|
|
578
|
+
mapping,
|
|
579
|
+
stateBits
|
|
580
|
+
};
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
// src/factory/optionalFactory.ts
|
|
584
|
+
var create7 = (descriptor, defaultState = false, name = "an optional") => {
|
|
585
|
+
if (descriptor[0] === null && descriptor[1] === null)
|
|
586
|
+
throw new Error("descriptor must have at least one non-null value");
|
|
587
|
+
if (descriptor[0] !== null && descriptor[1] !== null)
|
|
588
|
+
throw new Error("descriptor must have only one non-null value");
|
|
589
|
+
return {
|
|
590
|
+
type: "OPTIONAL",
|
|
591
|
+
state: defaultState,
|
|
592
|
+
descriptor,
|
|
593
|
+
value: JSON.parse(JSON.stringify(defaultState ? descriptor[1] : descriptor[0])),
|
|
594
|
+
name,
|
|
595
|
+
stateBits: 1
|
|
596
|
+
};
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
// src/factory/enumOptionsFactory.ts
|
|
600
|
+
var maxEnumOptions = 64;
|
|
601
|
+
var maxEnumOptionsBits = getMinimumBitsForInteger(maxEnumOptions);
|
|
602
|
+
var create8 = (descriptor, defaultState = 0, name = "enum options", options) => {
|
|
603
|
+
if (descriptor.length < 2)
|
|
604
|
+
throw new Error("descriptor must have at least two entries");
|
|
605
|
+
if (descriptor.length - 1 < defaultState)
|
|
606
|
+
throw new Error("defaultState must be less than the length of the descriptor");
|
|
607
|
+
const mapping = [];
|
|
608
|
+
if (options) {
|
|
609
|
+
const { max, mapping: mapping2 } = getEnumMaxAndMappingFromOptions(options);
|
|
610
|
+
if (max !== descriptor.length - 1)
|
|
611
|
+
throw new Error("max must be equal to the length of the descriptor - 1");
|
|
612
|
+
mapping2.push(...mapping2);
|
|
613
|
+
} else
|
|
614
|
+
mapping.push(...descriptor.map((_, i) => i));
|
|
615
|
+
return {
|
|
616
|
+
value: JSON.parse(JSON.stringify(descriptor[defaultState])),
|
|
617
|
+
descriptor,
|
|
618
|
+
name,
|
|
619
|
+
mapping,
|
|
620
|
+
type: "ENUM_OPTIONS",
|
|
621
|
+
stateBits: getBitsForIntegerNumber(descriptor.length, maxEnumOptionsBits),
|
|
622
|
+
state: defaultState
|
|
623
|
+
};
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
// src/factory/arrayFactory.ts
|
|
627
|
+
var maxArrayCount = 1024;
|
|
628
|
+
var create9 = (descriptor, defaultState = 0, minCount = 0, maxCount = 10, name = "an array") => {
|
|
629
|
+
if (!Number.isInteger(minCount) || !Number.isInteger(maxCount))
|
|
630
|
+
throw new Error("minCount and maxCount must be integers");
|
|
631
|
+
if (minCount < 0)
|
|
632
|
+
throw new Error("minCount must be at least 0");
|
|
633
|
+
if (maxCount < 0)
|
|
634
|
+
throw new Error("maxCount must be at least 0");
|
|
635
|
+
if (maxCount - minCount < 0)
|
|
636
|
+
throw new Error("maxCount must be greater than or equal to minCount");
|
|
637
|
+
if (maxCount - minCount > maxArrayCount)
|
|
638
|
+
throw new Error(`maxCount (${maxCount}) - minCount (${minCount}) = ${maxCount - minCount} must be less than or equal to maxArrayCount (${maxArrayCount})`);
|
|
639
|
+
if (defaultState < minCount || defaultState > maxCount)
|
|
640
|
+
throw new Error(`defaultState must be between minCount (${minCount}) and maxCount (${maxCount}), given defaultState is ${defaultState}`);
|
|
641
|
+
const stateBits = getMinimumBitsForInteger(maxCount - minCount);
|
|
642
|
+
return {
|
|
643
|
+
value: [...Array(defaultState)].map(() => JSON.parse(JSON.stringify(descriptor))),
|
|
644
|
+
descriptor,
|
|
645
|
+
type: "ARRAY",
|
|
646
|
+
minCount,
|
|
647
|
+
maxCount,
|
|
648
|
+
stateBits,
|
|
649
|
+
state: defaultState,
|
|
650
|
+
name
|
|
651
|
+
};
|
|
652
|
+
};
|
|
653
|
+
|
|
654
|
+
// src/factory/objectFactory.ts
|
|
655
|
+
var create10 = (descriptor, name = "an object") => {
|
|
656
|
+
return {
|
|
657
|
+
type: "OBJECT",
|
|
658
|
+
descriptor,
|
|
659
|
+
value: descriptor,
|
|
660
|
+
name,
|
|
661
|
+
stateBits: 0
|
|
662
|
+
};
|
|
663
|
+
};
|
|
664
|
+
|
|
665
|
+
// src/factory/factory.ts
|
|
666
|
+
var DataEntryFactory = {
|
|
667
|
+
FLOAT: create,
|
|
668
|
+
INT: create2,
|
|
669
|
+
ENUM: create5,
|
|
670
|
+
BOOLEAN: create3,
|
|
671
|
+
VERSION: create4,
|
|
672
|
+
ENUM_ARRAY: create6,
|
|
673
|
+
OPTIONAL: create7,
|
|
674
|
+
ENUM_OPTIONS: create8,
|
|
675
|
+
ARRAY: create9,
|
|
676
|
+
OBJECT: create10
|
|
677
|
+
};
|
|
678
|
+
var StateDescriptorFactoryMethod = create10;
|
|
679
|
+
// src/stateHandling/stateNode.ts
|
|
680
|
+
class StateNode {
|
|
681
|
+
parent;
|
|
682
|
+
root;
|
|
683
|
+
type;
|
|
684
|
+
name;
|
|
685
|
+
bitstring = "";
|
|
686
|
+
constructor(entry, parent) {
|
|
687
|
+
this.parent = parent;
|
|
688
|
+
this.root = parent ? parent.root : this;
|
|
689
|
+
this.type = entry.type;
|
|
690
|
+
this.name = entry.name;
|
|
691
|
+
}
|
|
692
|
+
updateUpstream = () => {
|
|
693
|
+
const newBitstring = this.getBitString();
|
|
694
|
+
if (newBitstring !== this.bitstring)
|
|
695
|
+
this.bitstring = newBitstring, this.parent && this.parent.updateUpstream();
|
|
696
|
+
};
|
|
697
|
+
getStateBits = () => {
|
|
698
|
+
throw new Error("not implemented for " + this.type);
|
|
699
|
+
};
|
|
700
|
+
getValueBits = () => dataEntryBitsStringifier(this.toDataEntry());
|
|
701
|
+
getBitString = () => {
|
|
702
|
+
if (HasStateBitsDataTypes.includes(this.type))
|
|
703
|
+
return this.getStateBits() + this.getValueBits();
|
|
704
|
+
return this.getValueBits();
|
|
705
|
+
};
|
|
706
|
+
getBase64String = () => parseBitsToBase64(this.bitstring);
|
|
707
|
+
getParentString = () => {
|
|
708
|
+
if (this.parent)
|
|
709
|
+
return `${this.parent.name}
|
|
710
|
+
↳${this.name}`;
|
|
711
|
+
else
|
|
712
|
+
return `root:"${this.getDescription()} - ${this.getBase64String()}"`;
|
|
713
|
+
};
|
|
714
|
+
getChildren = () => {
|
|
715
|
+
throw new Error("not implemented for " + this.type);
|
|
716
|
+
};
|
|
717
|
+
getDescription = () => this.name;
|
|
718
|
+
getChildrenStrings = () => {
|
|
719
|
+
const children = this.getChildren();
|
|
720
|
+
if (children.length === 0)
|
|
721
|
+
return [];
|
|
722
|
+
const strings = [];
|
|
723
|
+
children.forEach((child, level) => {
|
|
724
|
+
const indent = level < children.length - 1 ? "| " : " ";
|
|
725
|
+
if (child) {
|
|
726
|
+
strings.push(`|→"${child.getDescription()}"`);
|
|
727
|
+
for (const grandchild of child.getChildrenStrings())
|
|
728
|
+
strings.push(indent + grandchild);
|
|
729
|
+
} else
|
|
730
|
+
strings.push(`|→null`);
|
|
731
|
+
});
|
|
732
|
+
return strings;
|
|
733
|
+
};
|
|
734
|
+
toDataEntry = () => {
|
|
735
|
+
throw new Error("not implemented for " + this.type);
|
|
736
|
+
};
|
|
737
|
+
toString() {
|
|
738
|
+
return `${this.getParentString()}
|
|
739
|
+
${this.getChildrenStrings().join(`
|
|
740
|
+
`)}`;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
class SimpleStateNodes extends StateNode {
|
|
745
|
+
value;
|
|
746
|
+
descriptor;
|
|
747
|
+
constructor(entry, parent) {
|
|
748
|
+
super(entry, parent);
|
|
749
|
+
this.value = entry.value;
|
|
750
|
+
this.descriptor = entry;
|
|
751
|
+
this.bitstring = this.getBitString();
|
|
752
|
+
}
|
|
753
|
+
getChildren = () => [];
|
|
754
|
+
getDescription = () => `${this.name}: ${this.value}`;
|
|
755
|
+
updateValue = (value) => {
|
|
756
|
+
this.value = constrainValue7(this.descriptor, value);
|
|
757
|
+
this.updateUpstream();
|
|
758
|
+
};
|
|
759
|
+
toDataEntry = () => ({
|
|
760
|
+
...this.descriptor,
|
|
761
|
+
name: this.name,
|
|
762
|
+
value: this.value
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
class VersionNode extends SimpleStateNodes {
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
class BooleanNode extends SimpleStateNodes {
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
class EnumNode extends SimpleStateNodes {
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
class IntNode extends SimpleStateNodes {
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
class FloatNode extends SimpleStateNodes {
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
class EnumArrayNode extends SimpleStateNodes {
|
|
782
|
+
getStateBits = () => rawStateStringifier(this.value, this.descriptor.minCount, this.descriptor.stateBits);
|
|
783
|
+
getDescription = () => `${this.name}: [${this.value.map((v) => this.descriptor.mapping[v]).join(", ")}]`;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
class OptionalNode extends StateNode {
|
|
787
|
+
state;
|
|
788
|
+
stateBits;
|
|
789
|
+
descriptor;
|
|
790
|
+
child = null;
|
|
791
|
+
constructor(entry, parent) {
|
|
792
|
+
super(entry, parent);
|
|
793
|
+
this.state = entry.state;
|
|
794
|
+
this.stateBits = entry.stateBits;
|
|
795
|
+
this.descriptor = entry["descriptor"];
|
|
796
|
+
this.bitstring = this.getBitString();
|
|
797
|
+
}
|
|
798
|
+
getChildren = () => [this.child];
|
|
799
|
+
getStateBits = () => rawStateStringifier3(this.state);
|
|
800
|
+
getValueBits = () => this.child ? this.child.bitstring : "";
|
|
801
|
+
updateState = (newState) => {
|
|
802
|
+
this.state = constrainState(newState);
|
|
803
|
+
if (this.state === this.state)
|
|
804
|
+
return;
|
|
805
|
+
this.child = this.descriptor[this.state ? 1 : 0] ? NodeFactory(this.descriptor[this.state ? 1 : 0], this) : null;
|
|
806
|
+
this.updateUpstream();
|
|
807
|
+
};
|
|
808
|
+
toDataEntry = () => ({
|
|
809
|
+
type: "OPTIONAL",
|
|
810
|
+
name: this.name,
|
|
811
|
+
state: this.state,
|
|
812
|
+
stateBits: this.stateBits,
|
|
813
|
+
descriptor: this.descriptor,
|
|
814
|
+
value: this.child ? this.child.toDataEntry() : null
|
|
815
|
+
});
|
|
816
|
+
getDescription = () => `${this.name}: ${this.state}`;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
class EnumOptionsNode extends StateNode {
|
|
820
|
+
state;
|
|
821
|
+
stateBits;
|
|
822
|
+
descriptor;
|
|
823
|
+
mapping;
|
|
824
|
+
child = null;
|
|
825
|
+
constructor(entry, parent) {
|
|
826
|
+
super(entry, parent);
|
|
827
|
+
this.state = entry.state;
|
|
828
|
+
this.stateBits = entry.stateBits;
|
|
829
|
+
this.descriptor = entry["descriptor"];
|
|
830
|
+
this.mapping = entry["mapping"];
|
|
831
|
+
this.child = entry["value"] ? NodeFactory(entry["value"], this) : null;
|
|
832
|
+
this.bitstring = this.getBitString();
|
|
833
|
+
}
|
|
834
|
+
getChildren = () => [this.child];
|
|
835
|
+
getStateBits = () => rawStateStringifier4(this.state, this.stateBits);
|
|
836
|
+
getValueBits = () => this.child ? this.child.bitstring : "";
|
|
837
|
+
updateState = (newState) => {
|
|
838
|
+
const constrainedNewState = constrainState2(this.descriptor.length, newState);
|
|
839
|
+
if (constrainedNewState === this.state)
|
|
840
|
+
return;
|
|
841
|
+
const validationResult = validateDataEntry(this.descriptor[constrainedNewState], this.child ? this.child.toDataEntry() : null);
|
|
842
|
+
this.child = validationResult ? NodeFactory(validationResult, this) : null;
|
|
843
|
+
this.state = constrainedNewState;
|
|
844
|
+
this.updateUpstream();
|
|
845
|
+
};
|
|
846
|
+
toDataEntry = () => ({
|
|
847
|
+
type: "ENUM_OPTIONS",
|
|
848
|
+
name: this.name,
|
|
849
|
+
state: this.state,
|
|
850
|
+
stateBits: this.stateBits,
|
|
851
|
+
descriptor: this.descriptor,
|
|
852
|
+
mapping: this.mapping,
|
|
853
|
+
value: this.child ? this.child.toDataEntry() : null
|
|
854
|
+
});
|
|
855
|
+
getDescription = () => `${this.name}: ${this.state} of ${this.mapping.length} options`;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
class ArrayNode extends StateNode {
|
|
859
|
+
descriptor;
|
|
860
|
+
children;
|
|
861
|
+
minCount;
|
|
862
|
+
maxCount;
|
|
863
|
+
stateBits;
|
|
864
|
+
state;
|
|
865
|
+
constructor(entry, parent) {
|
|
866
|
+
super(entry, parent);
|
|
867
|
+
this.descriptor = entry["descriptor"];
|
|
868
|
+
this.children = entry["value"].map((child) => NodeFactory(child, this));
|
|
869
|
+
this.minCount = entry["minCount"];
|
|
870
|
+
this.maxCount = entry["maxCount"];
|
|
871
|
+
this.stateBits = entry["stateBits"];
|
|
872
|
+
this.state = entry["state"];
|
|
873
|
+
this.bitstring = this.getBitString();
|
|
874
|
+
}
|
|
875
|
+
getChildren = () => this.children;
|
|
876
|
+
getStateBits = () => rawStateStringifier2(this.state, this.minCount, this.stateBits);
|
|
877
|
+
getValueBits = () => this.children.map((child) => child.bitstring).join("");
|
|
878
|
+
updateState = (newState) => {
|
|
879
|
+
const constrainedNewState = constrainState3(newState, this.minCount, this.maxCount);
|
|
880
|
+
if (constrainedNewState === this.state)
|
|
881
|
+
return;
|
|
882
|
+
if (constrainedNewState < this.state)
|
|
883
|
+
this.children = this.children.slice(0, constrainedNewState);
|
|
884
|
+
else
|
|
885
|
+
for (let i = this.state;i < constrainedNewState; i++)
|
|
886
|
+
this.children.push(NodeFactory(this.descriptor, this));
|
|
887
|
+
this.state = constrainedNewState;
|
|
888
|
+
this.updateUpstream();
|
|
889
|
+
};
|
|
890
|
+
toDataEntry = () => ({
|
|
891
|
+
type: "ARRAY",
|
|
892
|
+
name: this.name,
|
|
893
|
+
value: this.children.map((child) => child.toDataEntry()),
|
|
894
|
+
minCount: this.minCount,
|
|
895
|
+
maxCount: this.maxCount,
|
|
896
|
+
stateBits: this.stateBits,
|
|
897
|
+
state: this.state,
|
|
898
|
+
descriptor: this.descriptor
|
|
899
|
+
});
|
|
900
|
+
getDescription = () => `${this.name}: ${this.state} of (${this.minCount}, ${this.maxCount})`;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
class ObjectNode extends StateNode {
|
|
904
|
+
descriptor;
|
|
905
|
+
children;
|
|
906
|
+
constructor(entry, parent) {
|
|
907
|
+
super(entry, parent);
|
|
908
|
+
this.descriptor = entry["descriptor"];
|
|
909
|
+
this.children = entry["value"].map((child) => NodeFactory(child, this));
|
|
910
|
+
this.bitstring = this.getBitString();
|
|
911
|
+
}
|
|
912
|
+
getChildren = () => this.children;
|
|
913
|
+
getStateBits = () => "";
|
|
914
|
+
getValueBits = () => this.children.map((child) => child.bitstring).join("");
|
|
915
|
+
toDataEntry = () => ({
|
|
916
|
+
type: "OBJECT",
|
|
917
|
+
name: this.name,
|
|
918
|
+
value: this.children.map((child) => child.toDataEntry()),
|
|
919
|
+
descriptor: this.descriptor,
|
|
920
|
+
stateBits: 0
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
var StateNodeMap = {
|
|
924
|
+
VERSION: VersionNode,
|
|
925
|
+
BOOLEAN: BooleanNode,
|
|
926
|
+
ENUM: EnumNode,
|
|
927
|
+
INT: IntNode,
|
|
928
|
+
FLOAT: FloatNode,
|
|
929
|
+
ENUM_ARRAY: EnumArrayNode,
|
|
930
|
+
OPTIONAL: OptionalNode,
|
|
931
|
+
ENUM_OPTIONS: EnumOptionsNode,
|
|
932
|
+
ARRAY: ArrayNode,
|
|
933
|
+
OBJECT: ObjectNode
|
|
934
|
+
};
|
|
935
|
+
var NodeFactory = (entry, parent) => new StateNodeMap[entry.type](entry, parent);
|
|
936
|
+
var GetStateNodeTree = (entries, name) => new ObjectNode(StateDescriptorFactoryMethod(entries, name), null);
|
|
937
|
+
var FromState = (stateDescriptor, name, base64String) => {
|
|
938
|
+
const bitstring = parseBase64ToBits(base64String);
|
|
939
|
+
const dataObject = StateDescriptorFactoryMethod(stateDescriptor, name);
|
|
940
|
+
const [parsedObject] = dataEntryBitstringParser(dataObject, bitstring);
|
|
941
|
+
return new ObjectNode(parsedObject, null);
|
|
942
|
+
};
|
|
641
943
|
// src/stateHandling/stateData.ts
|
|
642
|
-
var
|
|
944
|
+
var getObjectForDataEntries = (entries) => {
|
|
643
945
|
const object = {};
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
case "BOOLEAN":
|
|
647
|
-
object[item.name] = item.value;
|
|
648
|
-
break;
|
|
649
|
-
case "INT":
|
|
650
|
-
object[item.name] = item.value;
|
|
651
|
-
break;
|
|
652
|
-
case "ENUM":
|
|
653
|
-
object[item.name] = item.mapping[item.value];
|
|
654
|
-
break;
|
|
655
|
-
case "FLOAT":
|
|
656
|
-
object[item.name] = item.value;
|
|
657
|
-
break;
|
|
658
|
-
case "VERSION":
|
|
659
|
-
object[item.name] = item.value;
|
|
660
|
-
break;
|
|
661
|
-
case "ENUM_ARRAY":
|
|
662
|
-
object[item.name] = item.value.map((v) => item.mapping[v]);
|
|
663
|
-
break;
|
|
664
|
-
case "OPTIONAL":
|
|
665
|
-
object[item.name] = item.value === null ? null : getStateData(item.value);
|
|
666
|
-
break;
|
|
667
|
-
case "ENUM_OPTIONS":
|
|
668
|
-
object[item.name] = {
|
|
669
|
-
...getStateData(item.value),
|
|
670
|
-
state: item.state
|
|
671
|
-
};
|
|
672
|
-
break;
|
|
673
|
-
case "ARRAY":
|
|
674
|
-
object[item.name] = item.value.map(getStateData);
|
|
675
|
-
break;
|
|
676
|
-
}
|
|
946
|
+
entries.forEach((item) => {
|
|
947
|
+
object[item.name] = getStateData(item);
|
|
677
948
|
});
|
|
678
949
|
return object;
|
|
679
950
|
};
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
var getBitstringForStateDataEntry = (stateDataEntry2) => {
|
|
683
|
-
switch (stateDataEntry2.type) {
|
|
951
|
+
var getStateData = (entry) => {
|
|
952
|
+
switch (entry.type) {
|
|
684
953
|
case "BOOLEAN":
|
|
685
954
|
case "INT":
|
|
686
|
-
case "ENUM":
|
|
687
955
|
case "FLOAT":
|
|
688
956
|
case "VERSION":
|
|
957
|
+
return entry.value;
|
|
958
|
+
case "ENUM":
|
|
959
|
+
return entry.mapping[entry.value];
|
|
689
960
|
case "ENUM_ARRAY":
|
|
690
|
-
return
|
|
961
|
+
return entry.value.map((v) => entry.mapping[v]);
|
|
691
962
|
case "OPTIONAL":
|
|
692
|
-
return
|
|
963
|
+
return entry.value === null ? null : getStateData(entry.value);
|
|
693
964
|
case "ENUM_OPTIONS":
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
965
|
+
const state = entry.mapping[entry.state];
|
|
966
|
+
if (entry.value) {
|
|
967
|
+
switch (entry.value.type) {
|
|
968
|
+
case "OBJECT":
|
|
969
|
+
return {
|
|
970
|
+
...getStateData(entry.value),
|
|
971
|
+
state
|
|
972
|
+
};
|
|
973
|
+
default:
|
|
974
|
+
return { state, value: getStateData(entry.value) };
|
|
975
|
+
}
|
|
976
|
+
} else
|
|
977
|
+
return { state };
|
|
978
|
+
case "OBJECT":
|
|
979
|
+
return getObjectForDataEntries(entry.value);
|
|
705
980
|
case "ARRAY":
|
|
706
|
-
|
|
707
|
-
break;
|
|
708
|
-
case "ENUM_OPTIONS":
|
|
709
|
-
currenEntry.value = currenEntry.value.map((v) => getStateDataEntry(v, updateCallback));
|
|
710
|
-
break;
|
|
711
|
-
}
|
|
712
|
-
const newBitString = getBitstringForStateDataEntry(currenEntry);
|
|
713
|
-
currenEntry.bitstring = newBitString;
|
|
714
|
-
};
|
|
715
|
-
var updateStateDataEntry = (currenEntry, newEntry, updateCallback) => {
|
|
716
|
-
if (currenEntry.type !== newEntry.type || currenEntry.name !== newEntry.name)
|
|
717
|
-
throw new Error(`Types (${currenEntry.type} & ${newEntry.type}) or names (${currenEntry.name} & ${newEntry.name}) do not match`);
|
|
718
|
-
if (ComplexDataValues.includes(currenEntry.type)) {
|
|
719
|
-
if (currenEntry.state !== newEntry.state) {
|
|
720
|
-
const currentBitString = currenEntry.bitstring;
|
|
721
|
-
const updatedCurrentEntry = updateComplexValue(currenEntry, newEntry);
|
|
722
|
-
setComplexDataEntryValuesAsStateDataEntry(updatedCurrentEntry, updateCallback);
|
|
723
|
-
if (currentBitString !== updatedCurrentEntry.bitstring)
|
|
724
|
-
updateCallback();
|
|
725
|
-
}
|
|
726
|
-
} else {
|
|
727
|
-
const currentBitString = currenEntry.bitstring;
|
|
728
|
-
const updatedCurrentEntry = updateValue7(currenEntry, newEntry);
|
|
729
|
-
updatedCurrentEntry.bitstring = dataBitsStringifier(updatedCurrentEntry);
|
|
730
|
-
if (currentBitString !== updatedCurrentEntry.bitstring)
|
|
731
|
-
updateCallback();
|
|
981
|
+
return entry.value.map((v) => getStateData(v));
|
|
732
982
|
}
|
|
733
|
-
return currenEntry;
|
|
734
|
-
};
|
|
735
|
-
var getStateDataEntry = (entry, updateCallback) => {
|
|
736
|
-
entry.bitstring = getBitstringForStateDataEntry(entry);
|
|
737
|
-
entry.updateValue = (newEntry) => updateStateDataEntry(entry, newEntry, updateCallback);
|
|
738
|
-
return entry;
|
|
739
|
-
};
|
|
740
|
-
var createStateDataObject = (initialState, updateCallback) => {
|
|
741
|
-
const stateObject = {};
|
|
742
|
-
const wrappedUpdateCallback = () => {
|
|
743
|
-
stateObject.bitstring = getBitstringForStateNestedData(stateObject.state);
|
|
744
|
-
stateObject.base64 = parseBitsToBase64(stateObject.bitstring);
|
|
745
|
-
stateObject.data = getStateData(stateObject.state);
|
|
746
|
-
updateCallback(stateObject);
|
|
747
|
-
};
|
|
748
|
-
stateObject.state = initialState.map((item) => getStateDataEntry(item, wrappedUpdateCallback));
|
|
749
|
-
wrappedUpdateCallback();
|
|
750
|
-
return stateObject;
|
|
751
983
|
};
|
|
752
|
-
var getInitialStateFromBase64 = (base64, descriptor) => nestedDataBitstringParser(parseBase64ToBits(base64), descriptor)[0];
|
|
753
984
|
// src/utils/interpolateData.ts
|
|
754
985
|
var interpolateEntryAt = (dataEntry2, t) => {
|
|
755
986
|
const localT = Math.max(Math.min(1, t), 0);
|
|
@@ -766,8 +997,6 @@ var interpolateEntryAt = (dataEntry2, t) => {
|
|
|
766
997
|
case "FLOAT":
|
|
767
998
|
const v = dataEntry2.min + cosT * (dataEntry2.max - dataEntry2.min);
|
|
768
999
|
return dataEntryCorrecting({ ...dataEntry2, value: Math.min(dataEntry2.max, Math.max(v, dataEntry2.min)) });
|
|
769
|
-
case "ENUM_ARRAY":
|
|
770
|
-
return { ...dataEntry2, value: dataEntry2.value.map((v2) => Math.floor(localT * (v2 + 0.999))) };
|
|
771
1000
|
}
|
|
772
1001
|
};
|
|
773
1002
|
// src/utils/relativeValue.ts
|
|
@@ -782,30 +1011,36 @@ var getRelativeValue = (dataEntry2) => {
|
|
|
782
1011
|
return dataEntry2.value / (2 ** dataEntry2.bits - 1);
|
|
783
1012
|
case "ENUM":
|
|
784
1013
|
return dataEntry2.value / dataEntry2.max;
|
|
785
|
-
case "ENUM_ARRAY":
|
|
786
|
-
return dataEntry2.value.reduce((acc, v) => acc + v, 0) / dataEntry2.value.length;
|
|
787
1014
|
}
|
|
788
1015
|
};
|
|
789
1016
|
export {
|
|
790
|
-
valueBitsParser,
|
|
791
1017
|
parseBase64ToBits,
|
|
792
1018
|
interpolateEntryAt,
|
|
1019
|
+
getStateData,
|
|
793
1020
|
getRelativeValue,
|
|
794
1021
|
getOptionsFromMaxAndMapping,
|
|
795
|
-
getInitialStateFromBase64,
|
|
796
1022
|
getEnumMaxAndMappingFromOptions,
|
|
797
|
-
|
|
1023
|
+
getBitsCount6 as getBitsCount,
|
|
798
1024
|
dataEntryCorrecting,
|
|
799
1025
|
dataEntryBitstringParser,
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
complexDataStringifier,
|
|
804
|
-
complexDataStateStringifier,
|
|
1026
|
+
dataEntryBitsStringifier,
|
|
1027
|
+
VariableBitWidthDataTypes,
|
|
1028
|
+
StateNode,
|
|
805
1029
|
SignificandMaxBits,
|
|
806
1030
|
PROTECTED_ATTRIBUTE_NAMES,
|
|
1031
|
+
OptionalNode,
|
|
1032
|
+
ObjectNode,
|
|
1033
|
+
NodeFactory,
|
|
807
1034
|
IntegerMaxBits,
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
1035
|
+
IntNode,
|
|
1036
|
+
GetStateNodeTree,
|
|
1037
|
+
FromState,
|
|
1038
|
+
FloatNode,
|
|
1039
|
+
EnumOptionsNode,
|
|
1040
|
+
EnumNode,
|
|
1041
|
+
EnumArrayNode,
|
|
1042
|
+
DataEntryFactory,
|
|
1043
|
+
ConstantBitWidthDataTypes,
|
|
1044
|
+
BooleanNode,
|
|
1045
|
+
ArrayNode
|
|
811
1046
|
};
|