zstdify 1.1.2 → 1.3.0
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 +51 -2
- package/dist/bitstream/bitReaderReverse.d.ts +6 -0
- package/dist/bitstream/bitReaderReverse.js +51 -1
- package/dist/bitstream/bitReaderReverse.js.map +1 -1
- package/dist/bitstream/index.d.ts +1 -0
- package/dist/bitstream/index.js +1 -0
- package/dist/bitstream/index.js.map +1 -1
- package/dist/bitstream/reverseBitWriter.d.ts +1 -0
- package/dist/bitstream/reverseBitWriter.js +66 -0
- package/dist/bitstream/reverseBitWriter.js.map +1 -0
- package/dist/compress.js +47 -7
- package/dist/compress.js.map +1 -1
- package/dist/decode/debugTrace.d.ts +31 -0
- package/dist/decode/debugTrace.js +2 -0
- package/dist/decode/debugTrace.js.map +1 -0
- package/dist/decode/decompressFrame.d.ts +3 -1
- package/dist/decode/decompressFrame.js +153 -59
- package/dist/decode/decompressFrame.js.map +1 -1
- package/dist/decode/fusedSequences.d.ts +9 -0
- package/dist/decode/fusedSequences.js +26 -0
- package/dist/decode/fusedSequences.js.map +1 -0
- package/dist/decode/literals.js +164 -111
- package/dist/decode/literals.js.map +1 -1
- package/dist/decode/reconstruct.d.ts +33 -1
- package/dist/decode/reconstruct.js +591 -24
- package/dist/decode/reconstruct.js.map +1 -1
- package/dist/decode/sequences.d.ts +19 -7
- package/dist/decode/sequences.js +225 -133
- package/dist/decode/sequences.js.map +1 -1
- package/dist/decompress.d.ts +10 -0
- package/dist/decompress.js +5 -3
- package/dist/decompress.js.map +1 -1
- package/dist/encode/blockWriter.js +8 -2
- package/dist/encode/blockWriter.js.map +1 -1
- package/dist/encode/compressedBlock.d.ts +27 -1
- package/dist/encode/compressedBlock.js +594 -339
- package/dist/encode/compressedBlock.js.map +1 -1
- package/dist/encode/fastMatcher.d.ts +7 -0
- package/dist/encode/fastMatcher.js +13 -0
- package/dist/encode/fastMatcher.js.map +1 -0
- package/dist/encode/greedySequences.d.ts +9 -6
- package/dist/encode/greedySequences.js +21 -77
- package/dist/encode/greedySequences.js.map +1 -1
- package/dist/encode/lazyMatcher.d.ts +7 -0
- package/dist/encode/lazyMatcher.js +13 -0
- package/dist/encode/lazyMatcher.js.map +1 -0
- package/dist/encode/literalsEncoder.d.ts +14 -0
- package/dist/encode/literalsEncoder.js +343 -0
- package/dist/encode/literalsEncoder.js.map +1 -0
- package/dist/encode/optimalParser.d.ts +7 -0
- package/dist/encode/optimalParser.js +13 -0
- package/dist/encode/optimalParser.js.map +1 -0
- package/dist/encode/sequencePlanner.d.ts +23 -0
- package/dist/encode/sequencePlanner.js +280 -0
- package/dist/encode/sequencePlanner.js.map +1 -0
- package/dist/entropy/fse.d.ts +13 -6
- package/dist/entropy/fse.js +176 -13
- package/dist/entropy/fse.js.map +1 -1
- package/dist/entropy/huffman.d.ts +7 -5
- package/dist/entropy/huffman.js +18 -7
- package/dist/entropy/huffman.js.map +1 -1
- package/dist/entropy/index.d.ts +2 -2
- package/dist/entropy/weights.js +20 -14
- package/dist/entropy/weights.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,44 +6,95 @@ import { ZstdError } from '../errors.js';
|
|
|
6
6
|
import { validateContentChecksum } from '../frame/checksum.js';
|
|
7
7
|
import { parseBlockHeader } from './block.js';
|
|
8
8
|
import { decodeCompressedLiterals, decodeRawLiterals, decodeRLELiterals, decodeTreelessLiterals, parseLiteralsSectionHeader, } from './literals.js';
|
|
9
|
-
import {
|
|
9
|
+
import { appendRangeToHistoryWindow, appendRLEToHistoryWindow, appendToHistoryWindow, executeSequencesInto, executeSequencesIntoFast, getOrCreateHistoryWindow, } from './reconstruct.js';
|
|
10
|
+
import { decodeAndExecuteSequencesInto, shouldUseFusedSequencePath } from './fusedSequences.js';
|
|
10
11
|
import { decodeSequences } from './sequences.js';
|
|
11
|
-
export function decompressFrame(data, offset, header, dictionary, maxSize) {
|
|
12
|
+
export function decompressFrame(data, offset, header, dictionary, maxSize, validateChecksum = true, reuseContext, debugTrace) {
|
|
12
13
|
let pos = offset + 4 + header.headerSize;
|
|
13
|
-
const
|
|
14
|
+
const knownOutputSize = header.contentSize ?? null;
|
|
15
|
+
let outputBuffer = knownOutputSize !== null ? new Uint8Array(knownOutputSize) : new Uint8Array(0);
|
|
14
16
|
let totalSize = 0;
|
|
15
17
|
const repOffsets = dictionary?.repOffsets
|
|
16
18
|
? [dictionary.repOffsets[0], dictionary.repOffsets[1], dictionary.repOffsets[2]]
|
|
17
19
|
: [1, 4, 8];
|
|
18
|
-
|
|
19
|
-
if (dictionary?.historyPrefix && dictionary.historyPrefix.length > 0) {
|
|
20
|
-
history = dictionary.historyPrefix.slice();
|
|
21
|
-
}
|
|
20
|
+
const history = getOrCreateHistoryWindow(header.windowSize, dictionary?.historyPrefix, reuseContext);
|
|
22
21
|
let prevHuffmanTable = dictionary?.huffmanTable ?? null;
|
|
23
22
|
let prevSeqTables = dictionary?.sequenceTables ?? null;
|
|
23
|
+
const decodeMode = reuseContext?._decodeMode ?? 'fast';
|
|
24
|
+
const useFastPath = decodeMode !== 'reference';
|
|
25
|
+
const useFusedSequences = reuseContext?._useFusedSequences !== false;
|
|
26
|
+
const ensureOutputCapacity = (additional) => {
|
|
27
|
+
const needed = totalSize + additional;
|
|
28
|
+
if (needed <= outputBuffer.length) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
let nextCapacity = outputBuffer.length === 0 ? 64 * 1024 : outputBuffer.length;
|
|
32
|
+
while (nextCapacity < needed) {
|
|
33
|
+
nextCapacity *= 2;
|
|
34
|
+
}
|
|
35
|
+
const grown = new Uint8Array(nextCapacity);
|
|
36
|
+
if (totalSize > 0) {
|
|
37
|
+
grown.set(outputBuffer.subarray(0, totalSize), 0);
|
|
38
|
+
}
|
|
39
|
+
outputBuffer = grown;
|
|
40
|
+
};
|
|
41
|
+
const appendOutput = (chunk) => {
|
|
42
|
+
if (chunk.length === 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
ensureOutputCapacity(chunk.length);
|
|
46
|
+
outputBuffer.set(chunk, totalSize);
|
|
47
|
+
totalSize += chunk.length;
|
|
48
|
+
};
|
|
49
|
+
let blockIndex = 0;
|
|
50
|
+
const onBlockDecoded = debugTrace?.onBlockDecoded;
|
|
24
51
|
while (true) {
|
|
25
52
|
if (pos + 3 > data.length) {
|
|
26
53
|
throw new ZstdError('Block header truncated', 'corruption_detected');
|
|
27
54
|
}
|
|
55
|
+
const blockHeaderPos = pos;
|
|
28
56
|
const block = parseBlockHeader(data, pos);
|
|
29
57
|
pos += 3;
|
|
58
|
+
const blockOutputStart = totalSize;
|
|
59
|
+
let blockLiteralsInfo;
|
|
60
|
+
let blockSequencesInfo;
|
|
30
61
|
if (block.blockType === 0) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
62
|
+
if (pos + block.blockSize > data.length) {
|
|
63
|
+
throw new ZstdError('Raw literals truncated', 'corruption_detected');
|
|
64
|
+
}
|
|
65
|
+
ensureOutputCapacity(block.blockSize);
|
|
66
|
+
outputBuffer.set(data.subarray(pos, pos + block.blockSize), totalSize);
|
|
67
|
+
if (!block.lastBlock) {
|
|
68
|
+
appendRangeToHistoryWindow(history, data, pos, block.blockSize);
|
|
69
|
+
}
|
|
70
|
+
totalSize += block.blockSize;
|
|
35
71
|
pos += block.blockSize;
|
|
36
72
|
}
|
|
37
73
|
else if (block.blockType === 1) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
74
|
+
if (pos >= data.length) {
|
|
75
|
+
throw new ZstdError('RLE literals truncated', 'corruption_detected');
|
|
76
|
+
}
|
|
77
|
+
const byte = data[pos];
|
|
78
|
+
ensureOutputCapacity(block.blockSize);
|
|
79
|
+
outputBuffer.fill(byte, totalSize, totalSize + block.blockSize);
|
|
80
|
+
if (!block.lastBlock) {
|
|
81
|
+
appendRLEToHistoryWindow(history, byte, block.blockSize);
|
|
82
|
+
}
|
|
83
|
+
totalSize += block.blockSize;
|
|
42
84
|
pos += 1;
|
|
43
85
|
}
|
|
44
86
|
else if (block.blockType === 2) {
|
|
45
87
|
const blockContent = data.subarray(pos, pos + block.blockSize);
|
|
46
88
|
const { header: litHeader, dataOffset: litDataOffset } = parseLiteralsSectionHeader(blockContent, 0);
|
|
89
|
+
if (onBlockDecoded) {
|
|
90
|
+
blockLiteralsInfo = {
|
|
91
|
+
blockType: litHeader.blockType,
|
|
92
|
+
regeneratedSize: litHeader.regeneratedSize,
|
|
93
|
+
compressedSize: litHeader.compressedSize,
|
|
94
|
+
numStreams: litHeader.numStreams,
|
|
95
|
+
headerSize: litHeader.headerSize,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
47
98
|
let literals;
|
|
48
99
|
let litBytesConsumed;
|
|
49
100
|
if (litHeader.blockType === 0) {
|
|
@@ -69,35 +120,106 @@ export function decompressFrame(data, offset, header, dictionary, maxSize) {
|
|
|
69
120
|
litBytesConsumed = litHeader.headerSize + comp.bytesRead;
|
|
70
121
|
}
|
|
71
122
|
const seqSectionSize = block.blockSize - litBytesConsumed;
|
|
72
|
-
let output;
|
|
73
123
|
if (seqSectionSize <= 0) {
|
|
74
|
-
|
|
124
|
+
appendOutput(literals);
|
|
125
|
+
if (!block.lastBlock) {
|
|
126
|
+
appendToHistoryWindow(history, literals);
|
|
127
|
+
}
|
|
75
128
|
}
|
|
76
129
|
else {
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
130
|
+
const canUseFusedPath = useFastPath &&
|
|
131
|
+
useFusedSequences &&
|
|
132
|
+
shouldUseFusedSequencePath(seqSectionSize, literals.length, header.windowSize, !block.lastBlock);
|
|
133
|
+
if (canUseFusedPath) {
|
|
134
|
+
const start = totalSize;
|
|
135
|
+
const { written, seqResult } = decodeAndExecuteSequencesInto(blockContent, litBytesConsumed, seqSectionSize, prevSeqTables, reuseContext?._sequences, literals, header.windowSize, ensureOutputCapacity, () => outputBuffer, start, repOffsets, history, !block.lastBlock);
|
|
136
|
+
if (reuseContext) {
|
|
137
|
+
reuseContext._sequences = seqResult.sequences;
|
|
138
|
+
}
|
|
139
|
+
prevSeqTables = seqResult.tables;
|
|
140
|
+
if (onBlockDecoded) {
|
|
141
|
+
blockSequencesInfo = {
|
|
142
|
+
numSequences: seqResult.metadata.numSequences,
|
|
143
|
+
llMode: seqResult.metadata.llMode,
|
|
144
|
+
ofMode: seqResult.metadata.ofMode,
|
|
145
|
+
mlMode: seqResult.metadata.mlMode,
|
|
146
|
+
llTableLog: seqResult.metadata.llTableLog,
|
|
147
|
+
ofTableLog: seqResult.metadata.ofTableLog,
|
|
148
|
+
mlTableLog: seqResult.metadata.mlTableLog,
|
|
149
|
+
repeatOffsetCandidateCount: seqResult.metadata.repeatOffsetCandidateCount,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (seqResult.sequences.length === 0) {
|
|
153
|
+
appendOutput(literals);
|
|
154
|
+
if (!block.lastBlock) {
|
|
155
|
+
appendToHistoryWindow(history, literals);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
totalSize += written;
|
|
160
|
+
}
|
|
81
161
|
}
|
|
82
162
|
else {
|
|
83
|
-
|
|
163
|
+
const seqResult = decodeSequences(blockContent, litBytesConsumed, seqSectionSize, prevSeqTables, reuseContext?._sequences);
|
|
164
|
+
if (reuseContext) {
|
|
165
|
+
reuseContext._sequences = seqResult.sequences;
|
|
166
|
+
}
|
|
167
|
+
prevSeqTables = seqResult.tables;
|
|
168
|
+
if (onBlockDecoded) {
|
|
169
|
+
blockSequencesInfo = {
|
|
170
|
+
numSequences: seqResult.metadata.numSequences,
|
|
171
|
+
llMode: seqResult.metadata.llMode,
|
|
172
|
+
ofMode: seqResult.metadata.ofMode,
|
|
173
|
+
mlMode: seqResult.metadata.mlMode,
|
|
174
|
+
llTableLog: seqResult.metadata.llTableLog,
|
|
175
|
+
ofTableLog: seqResult.metadata.ofTableLog,
|
|
176
|
+
mlTableLog: seqResult.metadata.mlTableLog,
|
|
177
|
+
repeatOffsetCandidateCount: seqResult.metadata.repeatOffsetCandidateCount,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
if (seqResult.sequences.length === 0) {
|
|
181
|
+
appendOutput(literals);
|
|
182
|
+
if (!block.lastBlock) {
|
|
183
|
+
appendToHistoryWindow(history, literals);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const decodedSize = literals.length + seqResult.metadata.totalMatchLength;
|
|
188
|
+
ensureOutputCapacity(decodedSize);
|
|
189
|
+
const start = totalSize;
|
|
190
|
+
const written = useFastPath
|
|
191
|
+
? executeSequencesIntoFast(literals, seqResult.sequences, header.windowSize, outputBuffer, start, repOffsets, history, !block.lastBlock)
|
|
192
|
+
: executeSequencesInto(literals, seqResult.sequences, header.windowSize, outputBuffer, start, repOffsets, history, !block.lastBlock);
|
|
193
|
+
totalSize += written;
|
|
194
|
+
}
|
|
84
195
|
}
|
|
85
196
|
}
|
|
86
|
-
chunks.push(output);
|
|
87
|
-
totalSize += output.length;
|
|
88
|
-
history = appendToHistory(history, output, header.windowSize);
|
|
89
197
|
pos += block.blockSize;
|
|
90
198
|
}
|
|
91
199
|
else {
|
|
92
200
|
throw new ZstdError('Unsupported block type', 'corruption_detected');
|
|
93
201
|
}
|
|
202
|
+
if (onBlockDecoded) {
|
|
203
|
+
onBlockDecoded({
|
|
204
|
+
blockIndex,
|
|
205
|
+
blockType: block.blockType,
|
|
206
|
+
blockSize: block.blockSize,
|
|
207
|
+
lastBlock: block.lastBlock,
|
|
208
|
+
inputOffset: blockHeaderPos,
|
|
209
|
+
outputStart: blockOutputStart,
|
|
210
|
+
outputEnd: totalSize,
|
|
211
|
+
literals: blockLiteralsInfo,
|
|
212
|
+
sequences: blockSequencesInfo,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
blockIndex++;
|
|
94
216
|
if (maxSize !== undefined && totalSize > maxSize) {
|
|
95
217
|
throw new ZstdError('Decompressed size exceeds maxSize', 'parameter_unsupported');
|
|
96
218
|
}
|
|
97
219
|
if (block.lastBlock)
|
|
98
220
|
break;
|
|
99
221
|
}
|
|
100
|
-
const output =
|
|
222
|
+
const output = outputBuffer.subarray(0, totalSize);
|
|
101
223
|
if (header.contentSize !== null && output.length !== header.contentSize) {
|
|
102
224
|
throw new ZstdError('Frame content size mismatch', 'corruption_detected');
|
|
103
225
|
}
|
|
@@ -105,43 +227,15 @@ export function decompressFrame(data, offset, header, dictionary, maxSize) {
|
|
|
105
227
|
if (pos + 4 > data.length) {
|
|
106
228
|
throw new ZstdError('Content checksum truncated', 'corruption_detected');
|
|
107
229
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
230
|
+
if (validateChecksum) {
|
|
231
|
+
const storedChecksum = readU32LE(data, pos);
|
|
232
|
+
if (!validateContentChecksum(output, storedChecksum)) {
|
|
233
|
+
throw new ZstdError('Content checksum mismatch', 'corruption_detected');
|
|
234
|
+
}
|
|
111
235
|
}
|
|
112
236
|
pos += 4;
|
|
113
237
|
return { output, bytesConsumed: pos - offset };
|
|
114
238
|
}
|
|
115
239
|
return { output, bytesConsumed: pos - offset };
|
|
116
240
|
}
|
|
117
|
-
function appendToHistory(history, chunk, windowSize) {
|
|
118
|
-
if (windowSize <= 0 || chunk.length === 0) {
|
|
119
|
-
return history;
|
|
120
|
-
}
|
|
121
|
-
const maxHistory = Math.max(1, windowSize);
|
|
122
|
-
if (chunk.length >= maxHistory) {
|
|
123
|
-
return new Uint8Array(chunk.subarray(chunk.length - maxHistory));
|
|
124
|
-
}
|
|
125
|
-
const keepFromHistory = Math.min(history.length, maxHistory - chunk.length);
|
|
126
|
-
const next = new Uint8Array(keepFromHistory + chunk.length);
|
|
127
|
-
if (keepFromHistory > 0) {
|
|
128
|
-
next.set(history.subarray(history.length - keepFromHistory), 0);
|
|
129
|
-
}
|
|
130
|
-
next.set(chunk, keepFromHistory);
|
|
131
|
-
return next;
|
|
132
|
-
}
|
|
133
|
-
function concatenateChunks(chunks) {
|
|
134
|
-
if (chunks.length === 0)
|
|
135
|
-
return new Uint8Array(0);
|
|
136
|
-
if (chunks.length === 1)
|
|
137
|
-
return chunks[0];
|
|
138
|
-
const total = chunks.reduce((s, c) => s + c.length, 0);
|
|
139
|
-
const result = new Uint8Array(total);
|
|
140
|
-
let pos = 0;
|
|
141
|
-
for (const chunk of chunks) {
|
|
142
|
-
result.set(chunk, pos);
|
|
143
|
-
pos += chunk.length;
|
|
144
|
-
}
|
|
145
|
-
return result;
|
|
146
|
-
}
|
|
147
241
|
//# sourceMappingURL=decompressFrame.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decompressFrame.js","sourceRoot":"","sources":["../../src/decode/decompressFrame.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"decompressFrame.js","sourceRoot":"","sources":["../../src/decode/decompressFrame.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EACL,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,EACxB,qBAAqB,EAErB,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAChG,OAAO,EAAE,eAAe,EAAuB,MAAM,gBAAgB,CAAC;AAEtE,MAAM,UAAU,eAAe,CAC7B,IAAgB,EAChB,MAAc,EACd,MAAmB,EACnB,UAA4C,EAC5C,OAAgB,EAChB,gBAAgB,GAAG,IAAI,EACvB,YAA8B,EAC9B,UAAwB,EACuB;IAC/C,IAAI,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC;IACzC,MAAM,eAAe,GAAG,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC;IACnD,IAAI,YAAY,GAAG,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAClG,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,MAAM,UAAU,GAA6B,UAAU,EAAE,UAAU;QACjE,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAChF,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACd,MAAM,OAAO,GAAG,wBAAwB,CAAC,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;IACrG,IAAI,gBAAgB,GAGT,UAAU,EAAE,YAAY,IAAI,IAAI,CAAC;IAC5C,IAAI,aAAa,GAA0B,UAAU,EAAE,cAAc,IAAI,IAAI,CAAC;IAC9E,MAAM,UAAU,GAAG,YAAY,EAAE,WAAW,IAAI,MAAM,CAAC;IACvD,MAAM,WAAW,GAAG,UAAU,KAAK,WAAW,CAAC;IAC/C,MAAM,iBAAiB,GAAG,YAAY,EAAE,kBAAkB,KAAK,KAAK,CAAC;IAErE,MAAM,oBAAoB,GAAG,CAAC,UAAkB,EAAQ,EAAE,CAAC;QACzD,MAAM,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;QACtC,IAAI,MAAM,IAAI,YAAY,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QACD,IAAI,YAAY,GAAG,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC;QAC/E,OAAO,YAAY,GAAG,MAAM,EAAE,CAAC;YAC7B,YAAY,IAAI,CAAC,CAAC;QACpB,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;QAC3C,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAClB,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,YAAY,GAAG,KAAK,CAAC;IAAA,CACtB,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,KAAiB,EAAQ,EAAE,CAAC;QAChD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACnC,YAAY,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QACnC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;IAAA,CAC3B,CAAC;IAEF,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,cAAc,GAAG,UAAU,EAAE,cAAc,CAAC;IAClD,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,qBAAqB,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,cAAc,GAAG,GAAG,CAAC;QAC3B,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC1C,GAAG,IAAI,CAAC,CAAC;QACT,MAAM,gBAAgB,GAAG,SAAS,CAAC;QACnC,IAAI,iBAAsD,CAAC;QAC3D,IAAI,kBAAwD,CAAC;QAE7D,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YAC1B,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;gBACxC,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,qBAAqB,CAAC,CAAC;YACvE,CAAC;YACD,oBAAoB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACtC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;YACvE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACrB,0BAA0B,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YAClE,CAAC;YACD,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;YAC7B,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC;QACzB,CAAC;aAAM,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YACjC,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACvB,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,qBAAqB,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAE,CAAC;YACxB,oBAAoB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACtC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YAChE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACrB,wBAAwB,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YAC3D,CAAC;YACD,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC;YAC7B,GAAG,IAAI,CAAC,CAAC;QACX,CAAC;aAAM,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YAC/D,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,GAAG,0BAA0B,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;YACrG,IAAI,cAAc,EAAE,CAAC;gBACnB,iBAAiB,GAAG;oBAClB,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,eAAe,EAAE,SAAS,CAAC,eAAe;oBAC1C,cAAc,EAAE,SAAS,CAAC,cAAc;oBACxC,UAAU,EAAE,SAAS,CAAC,UAAU;oBAChC,UAAU,EAAE,SAAS,CAAC,UAAU;iBACjC,CAAC;YACJ,CAAC;YAED,IAAI,QAAoB,CAAC;YACzB,IAAI,gBAAwB,CAAC;YAE7B,IAAI,SAAS,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;gBAC9B,QAAQ,GAAG,iBAAiB,CAAC,YAAY,EAAE,aAAa,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;gBACrF,gBAAgB,GAAG,SAAS,CAAC,UAAU,GAAG,SAAS,CAAC,eAAe,CAAC;YACtE,CAAC;iBAAM,IAAI,SAAS,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;gBACrC,QAAQ,GAAG,iBAAiB,CAAC,YAAY,EAAE,aAAa,EAAE,SAAS,CAAC,eAAe,CAAC,CAAC;gBACrF,gBAAgB,GAAG,SAAS,CAAC,UAAU,GAAG,CAAC,CAAC;YAC9C,CAAC;iBAAM,IAAI,SAAS,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,GAAG,wBAAwB,CACnC,YAAY,EACZ,aAAa,EACb,SAAS,CAAC,cAAe,EACzB,SAAS,CAAC,eAAe,EACzB,SAAS,CAAC,UAAU,CACrB,CAAC;gBACF,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;gBACzB,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC;gBACrC,gBAAgB,GAAG,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;YAC3D,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACtB,MAAM,IAAI,SAAS,CAAC,kDAAkD,EAAE,qBAAqB,CAAC,CAAC;gBACjG,CAAC;gBACD,MAAM,IAAI,GAAG,sBAAsB,CACjC,YAAY,EACZ,aAAa,EACb,SAAS,CAAC,cAAe,EACzB,SAAS,CAAC,eAAe,EACzB,SAAS,CAAC,UAAU,EACpB,gBAAgB,CACjB,CAAC;gBACF,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;gBACzB,gBAAgB,GAAG,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;YAC3D,CAAC;YAED,MAAM,cAAc,GAAG,KAAK,CAAC,SAAS,GAAG,gBAAgB,CAAC;YAC1D,IAAI,cAAc,IAAI,CAAC,EAAE,CAAC;gBACxB,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;oBACrB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,eAAe,GACnB,WAAW;oBACX,iBAAiB;oBACjB,0BAA0B,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBACnG,IAAI,eAAe,EAAE,CAAC;oBACpB,MAAM,KAAK,GAAG,SAAS,CAAC;oBACxB,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,6BAA6B,CAC1D,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,EAAE,UAAU,EACxB,QAAQ,EACR,MAAM,CAAC,UAAU,EACjB,oBAAoB,EACpB,GAAG,EAAE,CAAC,YAAY,EAClB,KAAK,EACL,UAAU,EACV,OAAO,EACP,CAAC,KAAK,CAAC,SAAS,CACjB,CAAC;oBACF,IAAI,YAAY,EAAE,CAAC;wBACjB,YAAY,CAAC,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC;oBAChD,CAAC;oBACD,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC;oBACjC,IAAI,cAAc,EAAE,CAAC;wBACnB,kBAAkB,GAAG;4BACnB,YAAY,EAAE,SAAS,CAAC,QAAQ,CAAC,YAAY;4BAC7C,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;4BACjC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;4BACjC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;4BACjC,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,UAAU;4BACzC,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,UAAU;4BACzC,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,UAAU;4BACzC,0BAA0B,EAAE,SAAS,CAAC,QAAQ,CAAC,0BAA0B;yBAC1E,CAAC;oBACJ,CAAC;oBACD,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACrC,YAAY,CAAC,QAAQ,CAAC,CAAC;wBACvB,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;4BACrB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;wBAC3C,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,SAAS,IAAI,OAAO,CAAC;oBACvB,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,SAAS,GAAG,eAAe,CAC/B,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,EAAE,UAAU,CACzB,CAAC;oBACF,IAAI,YAAY,EAAE,CAAC;wBACjB,YAAY,CAAC,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC;oBAChD,CAAC;oBACD,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC;oBACjC,IAAI,cAAc,EAAE,CAAC;wBACnB,kBAAkB,GAAG;4BACnB,YAAY,EAAE,SAAS,CAAC,QAAQ,CAAC,YAAY;4BAC7C,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;4BACjC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;4BACjC,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM;4BACjC,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,UAAU;4BACzC,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,UAAU;4BACzC,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,UAAU;4BACzC,0BAA0B,EAAE,SAAS,CAAC,QAAQ,CAAC,0BAA0B;yBAC1E,CAAC;oBACJ,CAAC;oBACD,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACrC,YAAY,CAAC,QAAQ,CAAC,CAAC;wBACvB,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;4BACrB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;wBAC3C,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC;wBAC1E,oBAAoB,CAAC,WAAW,CAAC,CAAC;wBAClC,MAAM,KAAK,GAAG,SAAS,CAAC;wBACxB,MAAM,OAAO,GAAG,WAAW;4BACzB,CAAC,CAAC,wBAAwB,CACtB,QAAQ,EACR,SAAS,CAAC,SAAS,EACnB,MAAM,CAAC,UAAU,EACjB,YAAY,EACZ,KAAK,EACL,UAAU,EACV,OAAO,EACP,CAAC,KAAK,CAAC,SAAS,CACjB;4BACH,CAAC,CAAC,oBAAoB,CAClB,QAAQ,EACR,SAAS,CAAC,SAAS,EACnB,MAAM,CAAC,UAAU,EACjB,YAAY,EACZ,KAAK,EACL,UAAU,EACV,OAAO,EACP,CAAC,KAAK,CAAC,SAAS,CACjB,CAAC;wBACN,SAAS,IAAI,OAAO,CAAC;oBACvB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,GAAG,IAAI,KAAK,CAAC,SAAS,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,SAAS,CAAC,wBAAwB,EAAE,qBAAqB,CAAC,CAAC;QACvE,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACnB,cAAc,CAAC;gBACb,UAAU;gBACV,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,WAAW,EAAE,cAAc;gBAC3B,WAAW,EAAE,gBAAgB;gBAC7B,SAAS,EAAE,SAAS;gBACpB,QAAQ,EAAE,iBAAiB;gBAC3B,SAAS,EAAE,kBAAkB;aAC9B,CAAC,CAAC;QACL,CAAC;QACD,UAAU,EAAE,CAAC;QAEb,IAAI,OAAO,KAAK,SAAS,IAAI,SAAS,GAAG,OAAO,EAAE,CAAC;YACjD,MAAM,IAAI,SAAS,CAAC,mCAAmC,EAAE,uBAAuB,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,KAAK,CAAC,SAAS;YAAE,MAAM;IAC7B,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC;QACxE,MAAM,IAAI,SAAS,CAAC,6BAA6B,EAAE,qBAAqB,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;QAC9B,IAAI,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAC1B,MAAM,IAAI,SAAS,CAAC,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,cAAc,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC5C,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,CAAC;gBACrD,MAAM,IAAI,SAAS,CAAC,2BAA2B,EAAE,qBAAqB,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QACD,GAAG,IAAI,CAAC,CAAC;QACT,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,GAAG,MAAM,EAAE,CAAC;IACjD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,GAAG,MAAM,EAAE,CAAC;AAAA,CAChD"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PackedSequences } from './reconstruct.js';
|
|
2
|
+
import { type HistoryWindow } from './reconstruct.js';
|
|
3
|
+
import { type DecodeSequencesResult, type SequenceTables } from './sequences.js';
|
|
4
|
+
export interface FusedDecodeExecuteResult {
|
|
5
|
+
written: number;
|
|
6
|
+
seqResult: DecodeSequencesResult;
|
|
7
|
+
}
|
|
8
|
+
export declare function shouldUseFusedSequencePath(seqSize: number, literalsLength: number, windowSize: number, updateHistory: boolean): boolean;
|
|
9
|
+
export declare function decodeAndExecuteSequencesInto(blockContent: Uint8Array, seqOffset: number, seqSize: number, prevSeqTables: SequenceTables | null, sequenceReuse: PackedSequences | undefined, literals: Uint8Array, windowSize: number, ensureOutputCapacity: (additional: number) => void, getOutputBuffer: () => Uint8Array, outputStart: number, repOffsets: [number, number, number], history: HistoryWindow, updateHistory: boolean): FusedDecodeExecuteResult;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { executeSequencesIntoFast } from './reconstruct.js';
|
|
2
|
+
import { decodeSequences } from './sequences.js';
|
|
3
|
+
export function shouldUseFusedSequencePath(seqSize, literalsLength, windowSize, updateHistory) {
|
|
4
|
+
if (seqSize < 4) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
if (literalsLength === 0) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
// For very large windows with history tracking enabled, the non-fused route can be more stable.
|
|
11
|
+
if (updateHistory && windowSize > 8 * 1024 * 1024) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
export function decodeAndExecuteSequencesInto(blockContent, seqOffset, seqSize, prevSeqTables, sequenceReuse, literals, windowSize, ensureOutputCapacity, getOutputBuffer, outputStart, repOffsets, history, updateHistory) {
|
|
17
|
+
const seqResult = decodeSequences(blockContent, seqOffset, seqSize, prevSeqTables, sequenceReuse);
|
|
18
|
+
if (seqResult.sequences.length === 0) {
|
|
19
|
+
return { written: 0, seqResult };
|
|
20
|
+
}
|
|
21
|
+
ensureOutputCapacity(literals.length + seqResult.metadata.totalMatchLength);
|
|
22
|
+
const output = getOutputBuffer();
|
|
23
|
+
const written = executeSequencesIntoFast(literals, seqResult.sequences, windowSize, output, outputStart, repOffsets, history, updateHistory);
|
|
24
|
+
return { written, seqResult };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=fusedSequences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fusedSequences.js","sourceRoot":"","sources":["../../src/decode/fusedSequences.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAsB,MAAM,kBAAkB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAmD,MAAM,gBAAgB,CAAC;AAOlG,MAAM,UAAU,0BAA0B,CACxC,OAAe,EACf,cAAsB,EACtB,UAAkB,EAClB,aAAsB,EACb;IACT,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,gGAAgG;IAChG,IAAI,aAAa,IAAI,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;QAClD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AAAA,CACb;AAED,MAAM,UAAU,6BAA6B,CAC3C,YAAwB,EACxB,SAAiB,EACjB,OAAe,EACf,aAAoC,EACpC,aAA0C,EAC1C,QAAoB,EACpB,UAAkB,EAClB,oBAAkD,EAClD,eAAiC,EACjC,WAAmB,EACnB,UAAoC,EACpC,OAAsB,EACtB,aAAsB,EACI;IAC1B,MAAM,SAAS,GAAG,eAAe,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;IAClG,IAAI,SAAS,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC;IACnC,CAAC;IACD,oBAAoB,CAAC,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,wBAAwB,CACtC,QAAQ,EACR,SAAS,CAAC,SAAS,EACnB,UAAU,EACV,MAAM,EACN,WAAW,EACX,UAAU,EACV,OAAO,EACP,aAAa,CACd,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAAA,CAC/B"}
|