@jax-data-science/sci-image-visualizer 0.10.0 → 0.12.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/esm2022/index.mjs +7 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +70 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +11 -1
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +18 -2
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +9 -1
- package/esm2022/lib/implementations/osd/osd-tile-loading.mjs +71 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +1 -1
- package/esm2022/lib/implementations/osd/slice-cache.mjs +35 -6
- package/esm2022/lib/region-editor/region-editor.component.mjs +152 -4
- package/esm2022/lib/region-editor/region-persistence.service.mjs +9 -1
- package/esm2022/lib/region-import/label-classes.mjs +149 -0
- package/esm2022/lib/region-import/label-volume.mjs +225 -0
- package/esm2022/lib/region-import/ome-zarr-labels.mjs +253 -0
- package/esm2022/lib/region-import/open-annotations.mjs +289 -0
- package/esm2022/lib/region-import/region-import.mjs +71 -0
- package/esm2022/lib/region-import/zarr-codecs.mjs +167 -0
- package/esm2022/lib/region-import/zip.mjs +157 -0
- package/esm2022/lib/routing-visualizer.service.mjs +112 -7
- package/esm2022/lib/store/region-source-scope.mjs +19 -4
- package/esm2022/lib/store/region-store.service.mjs +64 -14
- package/esm2022/lib/visualizer/region-load.mjs +16 -1
- package/esm2022/lib/visualizer.component.mjs +28 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-a68Hw5rw.mjs} +2057 -196
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-a68Hw5rw.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-CvadfzjS.mjs} +4 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-CvadfzjS.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/index.d.ts +12 -0
- package/lib/contracts/image.contract.d.ts +7 -0
- package/lib/contracts/ports/region-io.port.d.ts +24 -0
- package/lib/contracts/region-editor-api.contract.d.ts +19 -1
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +40 -1
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +5 -0
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +2 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +2 -0
- package/lib/implementations/osd/osd-tile-loading.d.ts +43 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +14 -0
- package/lib/implementations/osd/slice-cache.d.ts +13 -3
- package/lib/region-editor/region-editor.component.d.ts +27 -0
- package/lib/region-editor/region-persistence.service.d.ts +5 -1
- package/lib/region-import/label-classes.d.ts +39 -0
- package/lib/region-import/label-volume.d.ts +35 -0
- package/lib/region-import/ome-zarr-labels.d.ts +36 -0
- package/lib/region-import/open-annotations.d.ts +73 -0
- package/lib/region-import/region-import.d.ts +46 -0
- package/lib/region-import/zarr-codecs.d.ts +14 -0
- package/lib/region-import/zip.d.ts +31 -0
- package/lib/routing-visualizer.service.d.ts +39 -1
- package/lib/store/region-source-scope.d.ts +8 -2
- package/lib/store/region-store.service.d.ts +15 -5
- package/lib/visualizer.component.d.ts +9 -0
- package/package.json +2 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chunk codecs of the zarr stores label images come in (OME-Zarr `labels/`): Blosc framing
|
|
3
|
+
* with its lz4, zstd or zlib inner codecs (zarr v2's default, as ome-zarr-py writes), zstd (zarr
|
|
4
|
+
* v3's default), gzip and zlib. Anything else throws rather than be decoded wrongly. Pure: usable
|
|
5
|
+
* from workers.
|
|
6
|
+
*
|
|
7
|
+
* The Blosc framing follows jit-bioformats' `Blosc` (the decoder JIT validated on SpatialData
|
|
8
|
+
* stores): `u8 version, u8 versionlz, u8 flags, u8 typesize, u32 nbytes, u32 blocksize,
|
|
9
|
+
* u32 cbytes`, then `u32 bstarts[nblocks]`, then blocks of `nstreams` sub-streams, each
|
|
10
|
+
* `i32 csize` + bytes (a stream whose csize equals its decoded size stored raw, a negative one a
|
|
11
|
+
* run of one byte). Flags: 0x1 byte-shuffle, 0x2 memcpyed, 0x4 bit-shuffle, 0x10 no-split, bits
|
|
12
|
+
* 5-7 the inner codec.
|
|
13
|
+
*/
|
|
14
|
+
import { decompress as zstdDecompress } from 'fzstd';
|
|
15
|
+
const BLOSC_CODECS = ['blosclz', 'lz4', 'snappy', 'zlib', 'zstd'];
|
|
16
|
+
/** Decode a Blosc frame. */
|
|
17
|
+
export async function bloscDecompress(frame, inflate = platformInflate) {
|
|
18
|
+
const view = new DataView(frame.buffer, frame.byteOffset, frame.byteLength);
|
|
19
|
+
if (frame.length < 16)
|
|
20
|
+
throw new Error('blosc: frame too short');
|
|
21
|
+
const flags = frame[2];
|
|
22
|
+
const typesize = frame[3];
|
|
23
|
+
const nbytes = view.getUint32(4, true);
|
|
24
|
+
const blocksize = view.getUint32(8, true);
|
|
25
|
+
const out = new Uint8Array(nbytes);
|
|
26
|
+
if (nbytes === 0)
|
|
27
|
+
return out;
|
|
28
|
+
if (flags & 0x2) {
|
|
29
|
+
out.set(frame.subarray(16, 16 + nbytes));
|
|
30
|
+
return out;
|
|
31
|
+
}
|
|
32
|
+
if (flags & 0x4)
|
|
33
|
+
throw new Error('blosc: bit-shuffle is not supported');
|
|
34
|
+
const code = flags >>> 5;
|
|
35
|
+
const codec = BLOSC_CODECS[code] ?? `code ${code}`;
|
|
36
|
+
if (codec !== 'lz4' && codec !== 'zstd' && codec !== 'zlib') {
|
|
37
|
+
throw new Error(`blosc: inner codec ${codec} is not supported (lz4, zstd or zlib)`);
|
|
38
|
+
}
|
|
39
|
+
const shuffle = (flags & 0x1) !== 0 && typesize > 1;
|
|
40
|
+
const noSplit = (flags & 0x10) !== 0;
|
|
41
|
+
const nblocks = Math.ceil(nbytes / blocksize);
|
|
42
|
+
const scratch = shuffle ? new Uint8Array(blocksize) : null;
|
|
43
|
+
for (let blk = 0; blk < nblocks; blk++) {
|
|
44
|
+
const bsize = Math.min(blocksize, nbytes - blk * blocksize);
|
|
45
|
+
const leftover = bsize !== blocksize;
|
|
46
|
+
const nstreams = !noSplit && !leftover ? typesize : 1;
|
|
47
|
+
const ssize = Math.floor(bsize / nstreams);
|
|
48
|
+
let p = view.getUint32(16 + blk * 4, true);
|
|
49
|
+
const block = scratch ?? out;
|
|
50
|
+
const base = scratch ? 0 : blk * blocksize;
|
|
51
|
+
for (let s = 0; s < nstreams; s++) {
|
|
52
|
+
const csize = view.getInt32(p, true);
|
|
53
|
+
p += 4;
|
|
54
|
+
const dst = base + s * ssize;
|
|
55
|
+
if (csize < 0) {
|
|
56
|
+
block.fill(-csize & 0xff, dst, dst + ssize);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const src = frame.subarray(p, p + csize);
|
|
60
|
+
if (csize === ssize) {
|
|
61
|
+
block.set(src, dst);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const dec = codec === 'lz4'
|
|
65
|
+
? lz4BlockDecompress(src, ssize)
|
|
66
|
+
: codec === 'zstd'
|
|
67
|
+
? zstdDecompress(src)
|
|
68
|
+
: await inflate(src, 'deflate');
|
|
69
|
+
if (dec.length !== ssize)
|
|
70
|
+
throw new Error(`blosc: ${codec} produced ${dec.length} of ${ssize} bytes`);
|
|
71
|
+
block.set(dec, dst);
|
|
72
|
+
}
|
|
73
|
+
p += csize;
|
|
74
|
+
}
|
|
75
|
+
if (scratch)
|
|
76
|
+
unshuffle(scratch, bsize, typesize, out, blk * blocksize);
|
|
77
|
+
}
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
/** Decode one LZ4 block (no frame) of `size` bytes. */
|
|
81
|
+
export function lz4BlockDecompress(src, size) {
|
|
82
|
+
const out = new Uint8Array(size);
|
|
83
|
+
let i = 0;
|
|
84
|
+
let o = 0;
|
|
85
|
+
while (i < src.length) {
|
|
86
|
+
const token = src[i++];
|
|
87
|
+
let literals = token >>> 4;
|
|
88
|
+
if (literals === 15) {
|
|
89
|
+
let b;
|
|
90
|
+
do {
|
|
91
|
+
b = src[i++];
|
|
92
|
+
literals += b;
|
|
93
|
+
} while (b === 255);
|
|
94
|
+
}
|
|
95
|
+
if (o + literals > size || i + literals > src.length)
|
|
96
|
+
throw new Error('lz4: literals overrun');
|
|
97
|
+
out.set(src.subarray(i, i + literals), o);
|
|
98
|
+
i += literals;
|
|
99
|
+
o += literals;
|
|
100
|
+
if (i >= src.length)
|
|
101
|
+
break; // the last sequence has no match
|
|
102
|
+
const offset = src[i] | (src[i + 1] << 8);
|
|
103
|
+
i += 2;
|
|
104
|
+
if (offset === 0 || offset > o)
|
|
105
|
+
throw new Error('lz4: bad match offset');
|
|
106
|
+
let length = (token & 15) + 4;
|
|
107
|
+
if ((token & 15) === 15) {
|
|
108
|
+
let b;
|
|
109
|
+
do {
|
|
110
|
+
b = src[i++];
|
|
111
|
+
length += b;
|
|
112
|
+
} while (b === 255);
|
|
113
|
+
}
|
|
114
|
+
if (o + length > size)
|
|
115
|
+
throw new Error('lz4: match overrun');
|
|
116
|
+
// Byte by byte: a match may overlap what it copies (a run).
|
|
117
|
+
for (let k = 0; k < length; k++, o++)
|
|
118
|
+
out[o] = out[o - offset];
|
|
119
|
+
}
|
|
120
|
+
if (o !== size)
|
|
121
|
+
throw new Error(`lz4: produced ${o} of ${size} bytes`);
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Decode a zarr chunk through `codecs`, outermost last as zarr lists them (v2: the one
|
|
126
|
+
* `compressor`; v3: the bytes-to-bytes codecs after `bytes`).
|
|
127
|
+
*/
|
|
128
|
+
export async function decodeChunk(bytes, codecs, inflate = platformInflate) {
|
|
129
|
+
let data = bytes;
|
|
130
|
+
for (const codec of [...codecs].reverse()) {
|
|
131
|
+
switch (codec.id) {
|
|
132
|
+
case 'blosc':
|
|
133
|
+
data = await bloscDecompress(data, inflate);
|
|
134
|
+
break;
|
|
135
|
+
case 'zstd':
|
|
136
|
+
data = zstdDecompress(data);
|
|
137
|
+
break;
|
|
138
|
+
case 'gzip':
|
|
139
|
+
data = await inflate(data, 'gzip');
|
|
140
|
+
break;
|
|
141
|
+
case 'zlib':
|
|
142
|
+
data = await inflate(data, 'deflate');
|
|
143
|
+
break;
|
|
144
|
+
default:
|
|
145
|
+
throw new Error(`zarr: codec ${codec.id} is not supported (blosc, zstd, gzip, zlib)`);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return data;
|
|
149
|
+
}
|
|
150
|
+
function unshuffle(src, len, typesize, dst, off) {
|
|
151
|
+
const n = Math.floor(len / typesize);
|
|
152
|
+
for (let j = 0; j < typesize; j++) {
|
|
153
|
+
const base = j * n;
|
|
154
|
+
for (let i = 0; i < n; i++)
|
|
155
|
+
dst[off + i * typesize + j] = src[base + i];
|
|
156
|
+
}
|
|
157
|
+
// Bytes past the last whole element are not shuffled.
|
|
158
|
+
for (let k = n * typesize; k < len; k++)
|
|
159
|
+
dst[off + k] = src[k];
|
|
160
|
+
}
|
|
161
|
+
async function platformInflate(bytes, format) {
|
|
162
|
+
if (typeof DecompressionStream === 'undefined')
|
|
163
|
+
throw new Error(`zarr: ${format} chunks need DecompressionStream`);
|
|
164
|
+
const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream(format));
|
|
165
|
+
return new Uint8Array(await new Response(stream).arrayBuffer());
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemFyci1jb2RlY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3JlZ2lvbi1pbXBvcnQvemFyci1jb2RlY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsT0FBTyxFQUFFLFVBQVUsSUFBSSxjQUFjLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFLckQsTUFBTSxZQUFZLEdBQUcsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFFbEUsNEJBQTRCO0FBQzVCLE1BQU0sQ0FBQyxLQUFLLFVBQVUsZUFBZSxDQUFDLEtBQWlCLEVBQUUsVUFBbUIsZUFBZTtJQUN6RixNQUFNLElBQUksR0FBRyxJQUFJLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzVFLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxFQUFFO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO0lBQ2pFLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdkMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDMUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkMsSUFBSSxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sR0FBRyxDQUFDO0lBQzdCLElBQUksS0FBSyxHQUFHLEdBQUcsRUFBRSxDQUFDO1FB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LElBQUksS0FBSyxDQUFDLFNBQVMsTUFBTSxrQ0FBa0MsQ0FBQyxDQUFDO0lBQ3JFLE1BQU0sTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsS0FBaUIsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsV0FBVyxDQUFDLElBQUksbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNuRyxPQUFPLElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUNsRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgY2h1bmsgY29kZWNzIG9mIHRoZSB6YXJyIHN0b3JlcyBsYWJlbCBpbWFnZXMgY29tZSBpbiAoT01FLVphcnIgYGxhYmVscy9gKTogQmxvc2MgZnJhbWluZ1xuICogd2l0aCBpdHMgbHo0LCB6c3RkIG9yIHpsaWIgaW5uZXIgY29kZWNzICh6YXJyIHYyJ3MgZGVmYXVsdCwgYXMgb21lLXphcnItcHkgd3JpdGVzKSwgenN0ZCAoemFyclxuICogdjMncyBkZWZhdWx0KSwgZ3ppcCBhbmQgemxpYi4gQW55dGhpbmcgZWxzZSB0aHJvd3MgcmF0aGVyIHRoYW4gYmUgZGVjb2RlZCB3cm9uZ2x5LiBQdXJlOiB1c2FibGVcbiAqIGZyb20gd29ya2Vycy5cbiAqXG4gKiBUaGUgQmxvc2MgZnJhbWluZyBmb2xsb3dzIGppdC1iaW9mb3JtYXRzJyBgQmxvc2NgICh0aGUgZGVjb2RlciBKSVQgdmFsaWRhdGVkIG9uIFNwYXRpYWxEYXRhXG4gKiBzdG9yZXMpOiBgdTggdmVyc2lvbiwgdTggdmVyc2lvbmx6LCB1OCBmbGFncywgdTggdHlwZXNpemUsIHUzMiBuYnl0ZXMsIHUzMiBibG9ja3NpemUsXG4gKiB1MzIgY2J5dGVzYCwgdGhlbiBgdTMyIGJzdGFydHNbbmJsb2Nrc11gLCB0aGVuIGJsb2NrcyBvZiBgbnN0cmVhbXNgIHN1Yi1zdHJlYW1zLCBlYWNoXG4gKiBgaTMyIGNzaXplYCArIGJ5dGVzIChhIHN0cmVhbSB3aG9zZSBjc2l6ZSBlcXVhbHMgaXRzIGRlY29kZWQgc2l6ZSBzdG9yZWQgcmF3LCBhIG5lZ2F0aXZlIG9uZSBhXG4gKiBydW4gb2Ygb25lIGJ5dGUpLiBGbGFnczogMHgxIGJ5dGUtc2h1ZmZsZSwgMHgyIG1lbWNweWVkLCAweDQgYml0LXNodWZmbGUsIDB4MTAgbm8tc3BsaXQsIGJpdHNcbiAqIDUtNyB0aGUgaW5uZXIgY29kZWMuXG4gKi9cbmltcG9ydCB7IGRlY29tcHJlc3MgYXMgenN0ZERlY29tcHJlc3MgfSBmcm9tICdmenN0ZCc7XG5cbi8qKiBJbmZsYXRlIGd6aXAgb3IgemxpYiBkYXRhIChkZWZhdWx0OiB0aGUgcGxhdGZvcm0ncyBgRGVjb21wcmVzc2lvblN0cmVhbWApLiAqL1xuZXhwb3J0IHR5cGUgSW5mbGF0ZSA9IChieXRlczogVWludDhBcnJheSwgZm9ybWF0OiAnZ3ppcCcgfCAnZGVmbGF0ZScpID0+IFByb21pc2U8VWludDhBcnJheT47XG5cbmNvbnN0IEJMT1NDX0NPREVDUyA9IFsnYmxvc2NseicsICdsejQnLCAnc25hcHB5JywgJ3psaWInLCAnenN0ZCddO1xuXG4vKiogRGVjb2RlIGEgQmxvc2MgZnJhbWUuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYmxvc2NEZWNvbXByZXNzKGZyYW1lOiBVaW50OEFycmF5LCBpbmZsYXRlOiBJbmZsYXRlID0gcGxhdGZvcm1JbmZsYXRlKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoZnJhbWUuYnVmZmVyLCBmcmFtZS5ieXRlT2Zmc2V0LCBmcmFtZS5ieXRlTGVuZ3RoKTtcbiAgaWYgKGZyYW1lLmxlbmd0aCA8IDE2KSB0aHJvdyBuZXcgRXJyb3IoJ2Jsb3NjOiBmcmFtZSB0b28gc2hvcnQnKTtcbiAgY29uc3QgZmxhZ3MgPSBmcmFtZVsyXTtcbiAgY29uc3QgdHlwZXNpemUgPSBmcmFtZVszXTtcbiAgY29uc3QgbmJ5dGVzID0gdmlldy5nZXRVaW50MzIoNCwgdHJ1ZSk7XG4gIGNvbnN0IGJsb2Nrc2l6ZSA9IHZpZXcuZ2V0VWludDMyKDgsIHRydWUpO1xuICBjb25zdCBvdXQgPSBuZXcgVWludDhBcnJheShuYnl0ZXMpO1xuICBpZiAobmJ5dGVzID09PSAwKSByZXR1cm4gb3V0O1xuICBpZiAoZmxhZ3MgJiAweDIpIHtcbiAgICBvdXQuc2V0KGZyYW1lLnN1YmFycmF5KDE2LCAxNiArIG5ieXRlcykpO1xuICAgIHJldHVybiBvdXQ7XG4gIH1cbiAgaWYgKGZsYWdzICYgMHg0KSB0aHJvdyBuZXcgRXJyb3IoJ2Jsb3NjOiBiaXQtc2h1ZmZsZSBpcyBub3Qgc3VwcG9ydGVkJyk7XG4gIGNvbnN0IGNvZGUgPSBmbGFncyA+Pj4gNTtcbiAgY29uc3QgY29kZWMgPSBCTE9TQ19DT0RFQ1NbY29kZV0gPz8gYGNvZGUgJHtjb2RlfWA7XG4gIGlmIChjb2RlYyAhPT0gJ2x6NCcgJiYgY29kZWMgIT09ICd6c3RkJyAmJiBjb2RlYyAhPT0gJ3psaWInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBibG9zYzogaW5uZXIgY29kZWMgJHtjb2RlY30gaXMgbm90IHN1cHBvcnRlZCAobHo0LCB6c3RkIG9yIHpsaWIpYCk7XG4gIH1cbiAgY29uc3Qgc2h1ZmZsZSA9IChmbGFncyAmIDB4MSkgIT09IDAgJiYgdHlwZXNpemUgPiAxO1xuICBjb25zdCBub1NwbGl0ID0gKGZsYWdzICYgMHgxMCkgIT09IDA7XG4gIGNvbnN0IG5ibG9ja3MgPSBNYXRoLmNlaWwobmJ5dGVzIC8gYmxvY2tzaXplKTtcbiAgY29uc3Qgc2NyYXRjaCA9IHNodWZmbGUgPyBuZXcgVWludDhBcnJheShibG9ja3NpemUpIDogbnVsbDtcbiAgZm9yIChsZXQgYmxrID0gMDsgYmxrIDwgbmJsb2NrczsgYmxrKyspIHtcbiAgICBjb25zdCBic2l6ZSA9IE1hdGgubWluKGJsb2Nrc2l6ZSwgbmJ5dGVzIC0gYmxrICogYmxvY2tzaXplKTtcbiAgICBjb25zdCBsZWZ0b3ZlciA9IGJzaXplICE9PSBibG9ja3NpemU7XG4gICAgY29uc3QgbnN0cmVhbXMgPSAhbm9TcGxpdCAmJiAhbGVmdG92ZXIgPyB0eXBlc2l6ZSA6IDE7XG4gICAgY29uc3Qgc3NpemUgPSBNYXRoLmZsb29yKGJzaXplIC8gbnN0cmVhbXMpO1xuICAgIGxldCBwID0gdmlldy5nZXRVaW50MzIoMTYgKyBibGsgKiA0LCB0cnVlKTtcbiAgICBjb25zdCBibG9jayA9IHNjcmF0Y2ggPz8gb3V0O1xuICAgIGNvbnN0IGJhc2UgPSBzY3JhdGNoID8gMCA6IGJsayAqIGJsb2Nrc2l6ZTtcbiAgICBmb3IgKGxldCBzID0gMDsgcyA8IG5zdHJlYW1zOyBzKyspIHtcbiAgICAgIGNvbnN0IGNzaXplID0gdmlldy5nZXRJbnQzMihwLCB0cnVlKTtcbiAgICAgIHAgKz0gNDtcbiAgICAgIGNvbnN0IGRzdCA9IGJhc2UgKyBzICogc3NpemU7XG4gICAgICBpZiAoY3NpemUgPCAwKSB7XG4gICAgICAgIGJsb2NrLmZpbGwoLWNzaXplICYgMHhmZiwgZHN0LCBkc3QgKyBzc2l6ZSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3JjID0gZnJhbWUuc3ViYXJyYXkocCwgcCArIGNzaXplKTtcbiAgICAgIGlmIChjc2l6ZSA9PT0gc3NpemUpIHtcbiAgICAgICAgYmxvY2suc2V0KHNyYywgZHN0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGRlYyA9XG4gICAgICAgICAgY29kZWMgPT09ICdsejQnXG4gICAgICAgICAgICA/IGx6NEJsb2NrRGVjb21wcmVzcyhzcmMsIHNzaXplKVxuICAgICAgICAgICAgOiBjb2RlYyA9PT0gJ3pzdGQnXG4gICAgICAgICAgICAgID8genN0ZERlY29tcHJlc3Moc3JjKVxuICAgICAgICAgICAgICA6IGF3YWl0IGluZmxhdGUoc3JjLCAnZGVmbGF0ZScpO1xuICAgICAgICBpZiAoZGVjLmxlbmd0aCAhPT0gc3NpemUpIHRocm93IG5ldyBFcnJvcihgYmxvc2M6ICR7Y29kZWN9IHByb2R1Y2VkICR7ZGVjLmxlbmd0aH0gb2YgJHtzc2l6ZX0gYnl0ZXNgKTtcbiAgICAgICAgYmxvY2suc2V0KGRlYywgZHN0KTtcbiAgICAgIH1cbiAgICAgIHAgKz0gY3NpemU7XG4gICAgfVxuICAgIGlmIChzY3JhdGNoKSB1bnNodWZmbGUoc2NyYXRjaCwgYnNpemUsIHR5cGVzaXplLCBvdXQsIGJsayAqIGJsb2Nrc2l6ZSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqIERlY29kZSBvbmUgTFo0IGJsb2NrIChubyBmcmFtZSkgb2YgYHNpemVgIGJ5dGVzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGx6NEJsb2NrRGVjb21wcmVzcyhzcmM6IFVpbnQ4QXJyYXksIHNpemU6IG51bWJlcik6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBvdXQgPSBuZXcgVWludDhBcnJheShzaXplKTtcbiAgbGV0IGkgPSAwO1xuICBsZXQgbyA9IDA7XG4gIHdoaWxlIChpIDwgc3JjLmxlbmd0aCkge1xuICAgIGNvbnN0IHRva2VuID0gc3JjW2krK107XG4gICAgbGV0IGxpdGVyYWxzID0gdG9rZW4gPj4+IDQ7XG4gICAgaWYgKGxpdGVyYWxzID09PSAxNSkge1xuICAgICAgbGV0IGI6IG51bWJlcjtcbiAgICAgIGRvIHtcbiAgICAgICAgYiA9IHNyY1tpKytdO1xuICAgICAgICBsaXRlcmFscyArPSBiO1xuICAgICAgfSB3aGlsZSAoYiA9PT0gMjU1KTtcbiAgICB9XG4gICAgaWYgKG8gKyBsaXRlcmFscyA+IHNpemUgfHwgaSArIGxpdGVyYWxzID4gc3JjLmxlbmd0aCkgdGhyb3cgbmV3IEVycm9yKCdsejQ6IGxpdGVyYWxzIG92ZXJydW4nKTtcbiAgICBvdXQuc2V0KHNyYy5zdWJhcnJheShpLCBpICsgbGl0ZXJhbHMpLCBvKTtcbiAgICBpICs9IGxpdGVyYWxzO1xuICAgIG8gKz0gbGl0ZXJhbHM7XG4gICAgaWYgKGkgPj0gc3JjLmxlbmd0aCkgYnJlYWs7IC8vIHRoZSBsYXN0IHNlcXVlbmNlIGhhcyBubyBtYXRjaFxuICAgIGNvbnN0IG9mZnNldCA9IHNyY1tpXSB8IChzcmNbaSArIDFdIDw8IDgpO1xuICAgIGkgKz0gMjtcbiAgICBpZiAob2Zmc2V0ID09PSAwIHx8IG9mZnNldCA+IG8pIHRocm93IG5ldyBFcnJvcignbHo0OiBiYWQgbWF0Y2ggb2Zmc2V0Jyk7XG4gICAgbGV0IGxlbmd0aCA9ICh0b2tlbiAmIDE1KSArIDQ7XG4gICAgaWYgKCh0b2tlbiAmIDE1KSA9PT0gMTUpIHtcbiAgICAgIGxldCBiOiBudW1iZXI7XG4gICAgICBkbyB7XG4gICAgICAgIGIgPSBzcmNbaSsrXTtcbiAgICAgICAgbGVuZ3RoICs9IGI7XG4gICAgICB9IHdoaWxlIChiID09PSAyNTUpO1xuICAgIH1cbiAgICBpZiAobyArIGxlbmd0aCA+IHNpemUpIHRocm93IG5ldyBFcnJvcignbHo0OiBtYXRjaCBvdmVycnVuJyk7XG4gICAgLy8gQnl0ZSBieSBieXRlOiBhIG1hdGNoIG1heSBvdmVybGFwIHdoYXQgaXQgY29waWVzIChhIHJ1bikuXG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBsZW5ndGg7IGsrKywgbysrKSBvdXRbb10gPSBvdXRbbyAtIG9mZnNldF07XG4gIH1cbiAgaWYgKG8gIT09IHNpemUpIHRocm93IG5ldyBFcnJvcihgbHo0OiBwcm9kdWNlZCAke299IG9mICR7c2l6ZX0gYnl0ZXNgKTtcbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBEZWNvZGUgYSB6YXJyIGNodW5rIHRocm91Z2ggYGNvZGVjc2AsIG91dGVybW9zdCBsYXN0IGFzIHphcnIgbGlzdHMgdGhlbSAodjI6IHRoZSBvbmVcbiAqIGBjb21wcmVzc29yYDsgdjM6IHRoZSBieXRlcy10by1ieXRlcyBjb2RlY3MgYWZ0ZXIgYGJ5dGVzYCkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWNvZGVDaHVuayhcbiAgYnl0ZXM6IFVpbnQ4QXJyYXksXG4gIGNvZGVjczogcmVhZG9ubHkgeyBpZDogc3RyaW5nOyBbazogc3RyaW5nXTogdW5rbm93biB9W10sXG4gIGluZmxhdGU6IEluZmxhdGUgPSBwbGF0Zm9ybUluZmxhdGUsXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgbGV0IGRhdGEgPSBieXRlcztcbiAgZm9yIChjb25zdCBjb2RlYyBvZiBbLi4uY29kZWNzXS5yZXZlcnNlKCkpIHtcbiAgICBzd2l0Y2ggKGNvZGVjLmlkKSB7XG4gICAgICBjYXNlICdibG9zYyc6XG4gICAgICAgIGRhdGEgPSBhd2FpdCBibG9zY0RlY29tcHJlc3MoZGF0YSwgaW5mbGF0ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnenN0ZCc6XG4gICAgICAgIGRhdGEgPSB6c3RkRGVjb21wcmVzcyhkYXRhKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdnemlwJzpcbiAgICAgICAgZGF0YSA9IGF3YWl0IGluZmxhdGUoZGF0YSwgJ2d6aXAnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICd6bGliJzpcbiAgICAgICAgZGF0YSA9IGF3YWl0IGluZmxhdGUoZGF0YSwgJ2RlZmxhdGUnKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHphcnI6IGNvZGVjICR7Y29kZWMuaWR9IGlzIG5vdCBzdXBwb3J0ZWQgKGJsb3NjLCB6c3RkLCBnemlwLCB6bGliKWApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGF0YTtcbn1cblxuZnVuY3Rpb24gdW5zaHVmZmxlKHNyYzogVWludDhBcnJheSwgbGVuOiBudW1iZXIsIHR5cGVzaXplOiBudW1iZXIsIGRzdDogVWludDhBcnJheSwgb2ZmOiBudW1iZXIpOiB2b2lkIHtcbiAgY29uc3QgbiA9IE1hdGguZmxvb3IobGVuIC8gdHlwZXNpemUpO1xuICBmb3IgKGxldCBqID0gMDsgaiA8IHR5cGVzaXplOyBqKyspIHtcbiAgICBjb25zdCBiYXNlID0gaiAqIG47XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIGRzdFtvZmYgKyBpICogdHlwZXNpemUgKyBqXSA9IHNyY1tiYXNlICsgaV07XG4gIH1cbiAgLy8gQnl0ZXMgcGFzdCB0aGUgbGFzdCB3aG9sZSBlbGVtZW50IGFyZSBub3Qgc2h1ZmZsZWQuXG4gIGZvciAobGV0IGsgPSBuICogdHlwZXNpemU7IGsgPCBsZW47IGsrKykgZHN0W29mZiArIGtdID0gc3JjW2tdO1xufVxuXG5hc3luYyBmdW5jdGlvbiBwbGF0Zm9ybUluZmxhdGUoYnl0ZXM6IFVpbnQ4QXJyYXksIGZvcm1hdDogJ2d6aXAnIHwgJ2RlZmxhdGUnKTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGlmICh0eXBlb2YgRGVjb21wcmVzc2lvblN0cmVhbSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgdGhyb3cgbmV3IEVycm9yKGB6YXJyOiAke2Zvcm1hdH0gY2h1bmtzIG5lZWQgRGVjb21wcmVzc2lvblN0cmVhbWApO1xuICBjb25zdCBzdHJlYW0gPSBuZXcgQmxvYihbYnl0ZXMgYXMgQmxvYlBhcnRdKS5zdHJlYW0oKS5waXBlVGhyb3VnaChuZXcgRGVjb21wcmVzc2lvblN0cmVhbShmb3JtYXQpKTtcbiAgcmV0dXJuIG5ldyBVaW50OEFycmF5KGF3YWl0IG5ldyBSZXNwb25zZShzdHJlYW0pLmFycmF5QnVmZmVyKCkpO1xufVxuIl19
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
const EOCD = 0x06054b50;
|
|
2
|
+
const ZIP64_LOCATOR = 0x07064b50;
|
|
3
|
+
const ZIP64_EOCD = 0x06064b50;
|
|
4
|
+
const CENTRAL = 0x02014b50;
|
|
5
|
+
const LOCAL = 0x04034b50;
|
|
6
|
+
const U32 = 0xffffffff;
|
|
7
|
+
/** Whether a file name is a zip archive. */
|
|
8
|
+
export function isZipName(name) {
|
|
9
|
+
return /\.zip$/i.test(name);
|
|
10
|
+
}
|
|
11
|
+
/** The members of the archive in `bytes` (directories and macOS metadata left out). */
|
|
12
|
+
export function readZip(bytes, inflateRaw = platformInflateRaw) {
|
|
13
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
14
|
+
const eocd = findEocd(view);
|
|
15
|
+
let count = view.getUint16(eocd + 10, true);
|
|
16
|
+
let dirOffset = view.getUint32(eocd + 16, true);
|
|
17
|
+
if (count === 0xffff || dirOffset === U32) {
|
|
18
|
+
const locator = eocd - 20;
|
|
19
|
+
if (locator < 0 || view.getUint32(locator, true) !== ZIP64_LOCATOR)
|
|
20
|
+
throw new Error('zip: ZIP64 locator missing');
|
|
21
|
+
const z64 = num(view, locator + 8);
|
|
22
|
+
if (view.getUint32(z64, true) !== ZIP64_EOCD)
|
|
23
|
+
throw new Error('zip: ZIP64 directory end missing');
|
|
24
|
+
count = num(view, z64 + 32);
|
|
25
|
+
dirOffset = num(view, z64 + 48);
|
|
26
|
+
}
|
|
27
|
+
const entries = [];
|
|
28
|
+
let at = dirOffset;
|
|
29
|
+
for (let i = 0; i < count; i++) {
|
|
30
|
+
if (view.getUint32(at, true) !== CENTRAL)
|
|
31
|
+
throw new Error('zip: bad central directory');
|
|
32
|
+
const flags = view.getUint16(at + 8, true);
|
|
33
|
+
const method = view.getUint16(at + 10, true);
|
|
34
|
+
const crc = view.getUint32(at + 16, true);
|
|
35
|
+
let compressed = view.getUint32(at + 20, true);
|
|
36
|
+
let size = view.getUint32(at + 24, true);
|
|
37
|
+
const nameLen = view.getUint16(at + 28, true);
|
|
38
|
+
const extraLen = view.getUint16(at + 30, true);
|
|
39
|
+
const commentLen = view.getUint16(at + 32, true);
|
|
40
|
+
let local = view.getUint32(at + 42, true);
|
|
41
|
+
const nameBytes = bytes.subarray(at + 46, at + 46 + nameLen);
|
|
42
|
+
const name = (flags & 0x800 ? new TextDecoder() : new TextDecoder('latin1'))
|
|
43
|
+
.decode(nameBytes)
|
|
44
|
+
.replace(/\\/g, '/');
|
|
45
|
+
// ZIP64: the 32-bit fields that overflowed are in the extra field, in this order.
|
|
46
|
+
let x = at + 46 + nameLen;
|
|
47
|
+
const extraEnd = x + extraLen;
|
|
48
|
+
while (x + 4 <= extraEnd) {
|
|
49
|
+
const id = view.getUint16(x, true);
|
|
50
|
+
const len = view.getUint16(x + 2, true);
|
|
51
|
+
if (id === 0x0001) {
|
|
52
|
+
let p = x + 4;
|
|
53
|
+
if (size === U32)
|
|
54
|
+
((size = num(view, p)), (p += 8));
|
|
55
|
+
if (compressed === U32)
|
|
56
|
+
((compressed = num(view, p)), (p += 8));
|
|
57
|
+
if (local === U32)
|
|
58
|
+
local = num(view, p);
|
|
59
|
+
}
|
|
60
|
+
x += 4 + len;
|
|
61
|
+
}
|
|
62
|
+
at = extraEnd + commentLen;
|
|
63
|
+
if (name.endsWith('/') || /(^|\/)__MACOSX\//.test(name) || /(^|\/)\.DS_Store$/.test(name))
|
|
64
|
+
continue;
|
|
65
|
+
const entry = { flags, method, crc, compressed, size, local };
|
|
66
|
+
entries.push({ name, size, bytes: () => readMember(bytes, view, name, entry, inflateRaw) });
|
|
67
|
+
}
|
|
68
|
+
return entries;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `files` with every `.zip` among them replaced by its members, named by their paths in it (a
|
|
72
|
+
* single top folder the archive wraps everything in is kept, as a folder pick would keep it).
|
|
73
|
+
*/
|
|
74
|
+
export async function expandZips(files, inflateRaw) {
|
|
75
|
+
const out = [];
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
if (!isZipName(file.name)) {
|
|
78
|
+
out.push(file);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
for (const entry of readZip(await file.bytes(), inflateRaw)) {
|
|
82
|
+
out.push({
|
|
83
|
+
name: entry.name,
|
|
84
|
+
bytes: () => entry.bytes(),
|
|
85
|
+
text: async () => new TextDecoder().decode(await entry.bytes()),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
async function readMember(bytes, view, name, m, inflateRaw) {
|
|
92
|
+
if (m.flags & 0x1)
|
|
93
|
+
throw new Error(`zip: ${name} is encrypted`);
|
|
94
|
+
if (view.getUint32(m.local, true) !== LOCAL)
|
|
95
|
+
throw new Error(`zip: ${name}: bad local header`);
|
|
96
|
+
const start = m.local + 30 + view.getUint16(m.local + 26, true) + view.getUint16(m.local + 28, true);
|
|
97
|
+
const raw = bytes.subarray(start, start + m.compressed);
|
|
98
|
+
if (raw.length !== m.compressed)
|
|
99
|
+
throw new Error(`zip: ${name} is truncated`);
|
|
100
|
+
let out;
|
|
101
|
+
if (m.method === 0)
|
|
102
|
+
out = raw;
|
|
103
|
+
else if (m.method === 8)
|
|
104
|
+
out = await inflateRaw(raw);
|
|
105
|
+
else
|
|
106
|
+
throw new Error(`zip: ${name} uses compression method ${m.method}, not stored or deflate`);
|
|
107
|
+
if (out.length !== m.size)
|
|
108
|
+
throw new Error(`zip: ${name} is ${out.length} bytes, expected ${m.size}`);
|
|
109
|
+
if (crc32(out) !== m.crc)
|
|
110
|
+
throw new Error(`zip: ${name} fails its CRC check`);
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
/** The end-of-central-directory record: the last one, within the 64 KiB a comment may take. */
|
|
114
|
+
function findEocd(view) {
|
|
115
|
+
const stop = Math.max(0, view.byteLength - 22 - 0xffff);
|
|
116
|
+
for (let at = view.byteLength - 22; at >= stop; at--) {
|
|
117
|
+
if (view.getUint32(at, true) === EOCD)
|
|
118
|
+
return at;
|
|
119
|
+
}
|
|
120
|
+
throw new Error('zip: not a zip archive (no central directory)');
|
|
121
|
+
}
|
|
122
|
+
/** A little-endian u64 that fits a double (archives under 8 PB). */
|
|
123
|
+
function num(view, at) {
|
|
124
|
+
return view.getUint32(at, true) + view.getUint32(at + 4, true) * 0x100000000;
|
|
125
|
+
}
|
|
126
|
+
let crcTable = null;
|
|
127
|
+
/** CRC-32 (IEEE), as zip records it. */
|
|
128
|
+
export function crc32(data) {
|
|
129
|
+
if (!crcTable) {
|
|
130
|
+
crcTable = new Uint32Array(256);
|
|
131
|
+
for (let n = 0; n < 256; n++) {
|
|
132
|
+
let c = n;
|
|
133
|
+
for (let k = 0; k < 8; k++)
|
|
134
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
135
|
+
crcTable[n] = c >>> 0;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
let c = 0xffffffff;
|
|
139
|
+
for (let i = 0; i < data.length; i++)
|
|
140
|
+
c = crcTable[(c ^ data[i]) & 0xff] ^ (c >>> 8);
|
|
141
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
142
|
+
}
|
|
143
|
+
async function platformInflateRaw(bytes) {
|
|
144
|
+
if (typeof DecompressionStream === 'undefined')
|
|
145
|
+
throw new Error('zip: deflated members need DecompressionStream');
|
|
146
|
+
let inflater;
|
|
147
|
+
try {
|
|
148
|
+
// Compression Streams' raw DEFLATE (Chrome 103, Firefox 113, Safari 16.4 on).
|
|
149
|
+
inflater = new DecompressionStream('deflate-raw');
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
throw new Error('zip: this browser cannot inflate zip members (no DecompressionStream "deflate-raw")');
|
|
153
|
+
}
|
|
154
|
+
const stream = new Blob([bytes]).stream().pipeThrough(inflater);
|
|
155
|
+
return new Uint8Array(await new Response(stream).arrayBuffer());
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemlwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9yZWdpb24taW1wb3J0L3ppcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkEsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDO0FBQ3hCLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQztBQUNqQyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUM7QUFDOUIsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDO0FBQzNCLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQztBQUN6QixNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUM7QUFFdkIsNENBQTRDO0FBQzVDLE1BQU0sVUFBVSxTQUFTLENBQUMsSUFBWTtJQUNwQyxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQUVELHVGQUF1RjtBQUN2RixNQUFNLFVBQVUsT0FBTyxDQUFDLEtBQWlCLEVBQUUsYUFBeUIsa0JBQWtCO0lBQ3BGLE1BQU0sSUFBSSxHQUFHLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUUsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1QyxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEQsSUFBSSxLQUFLLEtBQUssTUFBTSxJQUFJLFNBQVMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzFCLElBQUksT0FBTyxHQUFHLENBQUMsSUFBSSxJ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QUMsQ0FBQztJQUM1RSxPQUFPLElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUNsRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgbWVtYmVycyBvZiBhIGAuemlwYCwgcmVhZCBpbiB0aGUgYnJvd3NlcjogYW5ub3RhdGlvbnMgaGFuZGVkIG92ZXIgYXMgb25lIGFyY2hpdmUgKGEgZm9sZGVyXG4gKiBvZiBwZXItc2xpY2UgR2VvSlNPTiwgYSBsYWJlbCB2b2x1bWUgd2l0aCBpdHMgb250b2xvZ3ksIGFuIE9NRS1aYXJyIHN0b3JlJ3MgbGFiZWxzKS5cbiAqXG4gKiBPbmx5IHdoYXQgc3VjaCBhcmNoaXZlcyB1c2U6IHN0b3JlZCBvciBkZWZsYXRlZCBtZW1iZXJzLCBaSVA2NCBzaXplcyBhbmQgb2Zmc2V0cywgVVRGLTggb3JcbiAqIGxlZ2FjeSBuYW1lcy4gQW4gZW5jcnlwdGVkIG9yIG90aGVyd2lzZSBjb21wcmVzc2VkIG1lbWJlciB0aHJvd3Mgd2hlbiBpdCBpcyByZWFkLCByYXRoZXIgdGhhbiBiZVxuICogcmVhZCB3cm9uZ2x5OyBhIG1lbWJlcidzIENSQy0zMiBpcyBjaGVja2VkLiBNZW1iZXJzIGFyZSByZWFkIG9uIGRlbWFuZCwgc28gYW4gYXJjaGl2ZSBvZiBtYW55XG4gKiBjaHVua3MgKGEgemFyciBzdG9yZSkgaXMgbm90IGluZmxhdGVkIHdob2xlLiBQdXJlOiB1c2FibGUgZnJvbSB3b3JrZXJzLlxuICovXG5pbXBvcnQgdHlwZSB7IFJlZ2lvbkltcG9ydEZpbGUgfSBmcm9tICcuL3JlZ2lvbi1pbXBvcnQnO1xuXG4vKiogT25lIG1lbWJlciBvZiBhbiBhcmNoaXZlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBaaXBFbnRyeSB7XG4gIC8qKiBJdHMgcGF0aCBpbiB0aGUgYXJjaGl2ZSwgJy8nLXNlcGFyYXRlZC4gKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKiogSXRzIHVuY29tcHJlc3NlZCBzaXplLCBpbiBieXRlcy4gKi9cbiAgc2l6ZTogbnVtYmVyO1xuICBieXRlcygpOiBQcm9taXNlPFVpbnQ4QXJyYXk+O1xufVxuXG4vKiogSW5mbGF0ZSByYXcgREVGTEFURSBkYXRhIChkZWZhdWx0OiB0aGUgcGxhdGZvcm0ncyBgRGVjb21wcmVzc2lvblN0cmVhbSgnZGVmbGF0ZS1yYXcnKWApLiAqL1xuZXhwb3J0IHR5cGUgSW5mbGF0ZVJhdyA9IChieXRlczogVWludDhBcnJheSkgPT4gUHJvbWlzZTxVaW50OEFycmF5PjtcblxuY29uc3QgRU9DRCA9IDB4MDYwNTRiNTA7XG5jb25zdCBaSVA2NF9MT0NBVE9SID0gMHgwNzA2NGI1MDtcbmNvbnN0IFpJUDY0X0VPQ0QgPSAweDA2MDY0YjUwO1xuY29uc3QgQ0VOVFJBTCA9IDB4MDIwMTRiNTA7XG5jb25zdCBMT0NBTCA9IDB4MDQwMzRiNTA7XG5jb25zdCBVMzIgPSAweGZmZmZmZmZmO1xuXG4vKiogV2hldGhlciBhIGZpbGUgbmFtZSBpcyBhIHppcCBhcmNoaXZlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzWmlwTmFtZShuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9cXC56aXAkL2kudGVzdChuYW1lKTtcbn1cblxuLyoqIFRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGluIGBieXRlc2AgKGRpcmVjdG9yaWVzIGFuZCBtYWNPUyBtZXRhZGF0YSBsZWZ0IG91dCkuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZFppcChieXRlczogVWludDhBcnJheSwgaW5mbGF0ZVJhdzogSW5mbGF0ZVJhdyA9IHBsYXRmb3JtSW5mbGF0ZVJhdyk6IFppcEVudHJ5W10ge1xuICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KGJ5dGVzLmJ1ZmZlciwgYnl0ZXMuYnl0ZU9mZnNldCwgYnl0ZXMuYnl0ZUxlbmd0aCk7XG4gIGNvbnN0IGVvY2QgPSBmaW5kRW9jZCh2aWV3KTtcbiAgbGV0IGNvdW50ID0gdmlldy5nZXRVaW50MTYoZW9jZCArIDEwLCB0cnVlKTtcbiAgbGV0IGRpck9mZnNldCA9IHZpZXcuZ2V0VWludDMyKGVvY2QgKyAxNiwgdHJ1ZSk7XG4gIGlmIChjb3VudCA9PT0gMHhmZmZmIHx8IGRpck9mZnNldCA9PT0gVTMyKSB7XG4gICAgY29uc3QgbG9jYXRvciA9IGVvY2QgLSAyMDtcbiAgICBpZiAobG9jYXRvciA8IDAgfHwgdmlldy5nZXRVaW50MzIobG9jYXRvciwgdHJ1ZSkgIT09IFpJUDY0X0xPQ0FUT1IpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ppcDogWklQNjQgbG9jYXRvciBtaXNzaW5nJyk7XG4gICAgY29uc3QgejY0ID0gbnVtKHZpZXcsIGxvY2F0b3IgKyA4KTtcbiAgICBpZiAodmlldy5nZXRVaW50MzIoejY0LCB0cnVlKSAhPT0gWklQNjRfRU9DRCkgdGhyb3cgbmV3IEVycm9yKCd6aXA6IFpJUDY0IGRpcmVjdG9yeSBlbmQgbWlzc2luZycpO1xuICAgIGNvdW50ID0gbnVtKHZpZXcsIHo2NCArIDMyKTtcbiAgICBkaXJPZmZzZXQgPSBudW0odmlldywgejY0ICsgNDgpO1xuICB9XG4gIGNvbnN0IGVudHJpZXM6IFppcEVudHJ5W10gPSBbXTtcbiAgbGV0IGF0ID0gZGlyT2Zmc2V0O1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICBpZiAodmlldy5nZXRVaW50MzIoYXQsIHRydWUpICE9PSBDRU5UUkFMKSB0aHJvdyBuZXcgRXJyb3IoJ3ppcDogYmFkIGNlbnRyYWwgZGlyZWN0b3J5Jyk7XG4gICAgY29uc3QgZmxhZ3MgPSB2aWV3LmdldFVpbnQxNihhdCArIDgsIHRydWUpO1xuICAgIGNvbnN0IG1ldGhvZCA9IHZpZXcuZ2V0VWludDE2KGF0ICsgMTAsIHRydWUpO1xuICAgIGNvbnN0IGNyYyA9IHZpZXcuZ2V0VWludDMyKGF0ICsgMTYsIHRydWUpO1xuICAgIGxldCBjb21wcmVzc2VkID0gdmlldy5nZXRVaW50MzIoYXQgKyAyMCwgdHJ1ZSk7XG4gICAgbGV0IHNpemUgPSB2aWV3LmdldFVpbnQzMihhdCArIDI0LCB0cnVlKTtcbiAgICBjb25zdCBuYW1lTGVuID0gdmlldy5nZXRVaW50MTYoYXQgKyAyOCwgdHJ1ZSk7XG4gICAgY29uc3QgZXh0cmFMZW4gPSB2aWV3LmdldFVpbnQxNihhdCArIDMwLCB0cnVlKTtcbiAgICBjb25zdCBjb21tZW50TGVuID0gdmlldy5nZXRVaW50MTYoYXQgKyAzMiwgdHJ1ZSk7XG4gICAgbGV0IGxvY2FsID0gdmlldy5nZXRVaW50MzIoYXQgKyA0MiwgdHJ1ZSk7XG4gICAgY29uc3QgbmFtZUJ5dGVzID0gYnl0ZXMuc3ViYXJyYXkoYXQgKyA0NiwgYXQgKyA0NiArIG5hbWVMZW4pO1xuICAgIGNvbnN0IG5hbWUgPSAoZmxhZ3MgJiAweDgwMCA/IG5ldyBUZXh0RGVjb2RlcigpIDogbmV3IFRleHREZWNvZGVyKCdsYXRpbjEnKSlcbiAgICAgIC5kZWNvZGUobmFtZUJ5dGVzKVxuICAgICAgLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAvLyBaSVA2NDogdGhlIDMyLWJpdCBmaWVsZHMgdGhhdCBvdmVyZmxvd2VkIGFyZSBpbiB0aGUgZXh0cmEgZmllbGQsIGluIHRoaXMgb3JkZXIuXG4gICAgbGV0IHggPSBhdCArIDQ2ICsgbmFtZUxlbjtcbiAgICBjb25zdCBleHRyYUVuZCA9IHggKyBleHRyYUxlbjtcbiAgICB3aGlsZSAoeCArIDQgPD0gZXh0cmFFbmQpIHtcbiAgICAgIGNvbnN0IGlkID0gdmlldy5nZXRVaW50MTYoeCwgdHJ1ZSk7XG4gICAgICBjb25zdCBsZW4gPSB2aWV3LmdldFVpbnQxNih4ICsgMiwgdHJ1ZSk7XG4gICAgICBpZiAoaWQgPT09IDB4MDAwMSkge1xuICAgICAgICBsZXQgcCA9IHggKyA0O1xuICAgICAgICBpZiAoc2l6ZSA9PT0gVTMyKSAoKHNpemUgPSBudW0odmlldywgcCkpLCAocCArPSA4KSk7XG4gICAgICAgIGlmIChjb21wcmVzc2VkID09PSBVMzIpICgoY29tcHJlc3NlZCA9IG51bSh2aWV3LCBwKSksIChwICs9IDgpKTtcbiAgICAgICAgaWYgKGxvY2FsID09PSBVMzIpIGxvY2FsID0gbnVtKHZpZXcsIHApO1xuICAgICAgfVxuICAgICAgeCArPSA0ICsgbGVuO1xuICAgIH1cbiAgICBhdCA9IGV4dHJhRW5kICsgY29tbWVudExlbjtcbiAgICBpZiAobmFtZS5lbmRzV2l0aCgnLycpIHx8IC8oXnxcXC8pX19NQUNPU1hcXC8vLnRlc3QobmFtZSkgfHwgLyhefFxcLylcXC5EU19TdG9yZSQvLnRlc3QobmFtZSkpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGVudHJ5ID0geyBmbGFncywgbWV0aG9kLCBjcmMsIGNvbXByZXNzZWQsIHNpemUsIGxvY2FsIH07XG4gICAgZW50cmllcy5wdXNoKHsgbmFtZSwgc2l6ZSwgYnl0ZXM6ICgpID0+IHJlYWRNZW1iZXIoYnl0ZXMsIHZpZXcsIG5hbWUsIGVudHJ5LCBpbmZsYXRlUmF3KSB9KTtcbiAgfVxuICByZXR1cm4gZW50cmllcztcbn1cblxuLyoqXG4gKiBgZmlsZXNgIHdpdGggZXZlcnkgYC56aXBgIGFtb25nIHRoZW0gcmVwbGFjZWQgYnkgaXRzIG1lbWJlcnMsIG5hbWVkIGJ5IHRoZWlyIHBhdGhzIGluIGl0IChhXG4gKiBzaW5nbGUgdG9wIGZvbGRlciB0aGUgYXJjaGl2ZSB3cmFwcyBldmVyeXRoaW5nIGluIGlzIGtlcHQsIGFzIGEgZm9sZGVyIHBpY2sgd291bGQga2VlcCBpdCkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHBhbmRaaXBzKFxuICBmaWxlczogcmVhZG9ubHkgUmVnaW9uSW1wb3J0RmlsZVtdLFxuICBpbmZsYXRlUmF3PzogSW5mbGF0ZVJhdyxcbik6IFByb21pc2U8UmVnaW9uSW1wb3J0RmlsZVtdPiB7XG4gIGNvbnN0IG91dDogUmVnaW9uSW1wb3J0RmlsZVtdID0gW107XG4gIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgIGlmICghaXNaaXBOYW1lKGZpbGUubmFtZSkpIHtcbiAgICAgIG91dC5wdXNoKGZpbGUpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcmVhZFppcChhd2FpdCBmaWxlLmJ5dGVzKCksIGluZmxhdGVSYXcpKSB7XG4gICAgICBvdXQucHVzaCh7XG4gICAgICAgIG5hbWU6IGVudHJ5Lm5hbWUsXG4gICAgICAgIGJ5dGVzOiAoKSA9PiBlbnRyeS5ieXRlcygpLFxuICAgICAgICB0ZXh0OiBhc3luYyAoKSA9PiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoYXdhaXQgZW50cnkuYnl0ZXMoKSksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuaW50ZXJmYWNlIE1lbWJlciB7XG4gIGZsYWdzOiBudW1iZXI7XG4gIG1ldGhvZDogbnVtYmVyO1xuICBjcmM6IG51bWJlcjtcbiAgY29tcHJlc3NlZDogbnVtYmVyO1xuICBzaXplOiBudW1iZXI7XG4gIGxvY2FsOiBudW1iZXI7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNZW1iZXIoXG4gIGJ5dGVzOiBVaW50OEFycmF5LFxuICB2aWV3OiBEYXRhVmlldyxcbiAgbmFtZTogc3RyaW5nLFxuICBtOiBNZW1iZXIsXG4gIGluZmxhdGVSYXc6IEluZmxhdGVSYXcsXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgaWYgKG0uZmxhZ3MgJiAweDEpIHRocm93IG5ldyBFcnJvcihgemlwOiAke25hbWV9IGlzIGVuY3J5cHRlZGApO1xuICBpZiAodmlldy5nZXRVaW50MzIobS5sb2NhbCwgdHJ1ZSkgIT09IExPQ0FMKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfTogYmFkIGxvY2FsIGhlYWRlcmApO1xuICBjb25zdCBzdGFydCA9IG0ubG9jYWwgKyAzMCArIHZpZXcuZ2V0VWludDE2KG0ubG9jYWwgKyAyNiwgdHJ1ZSkgKyB2aWV3LmdldFVpbnQxNihtLmxvY2FsICsgMjgsIHRydWUpO1xuICBjb25zdCByYXcgPSBieXRlcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBtLmNvbXByZXNzZWQpO1xuICBpZiAocmF3Lmxlbmd0aCAhPT0gbS5jb21wcmVzc2VkKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfSBpcyB0cnVuY2F0ZWRgKTtcbiAgbGV0IG91dDogVWludDhBcnJheTtcbiAgaWYgKG0ubWV0aG9kID09PSAwKSBvdXQgPSByYXc7XG4gIGVsc2UgaWYgKG0ubWV0aG9kID09PSA4KSBvdXQgPSBhd2FpdCBpbmZsYXRlUmF3KHJhdyk7XG4gIGVsc2UgdGhyb3cgbmV3IEVycm9yKGB6aXA6ICR7bmFtZX0gdXNlcyBjb21wcmVzc2lvbiBtZXRob2QgJHttLm1ldGhvZH0sIG5vdCBzdG9yZWQgb3IgZGVmbGF0ZWApO1xuICBpZiAob3V0Lmxlbmd0aCAhPT0gbS5zaXplKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfSBpcyAke291dC5sZW5ndGh9IGJ5dGVzLCBleHBlY3RlZCAke20uc2l6ZX1gKTtcbiAgaWYgKGNyYzMyKG91dCkgIT09IG0uY3JjKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfSBmYWlscyBpdHMgQ1JDIGNoZWNrYCk7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBUaGUgZW5kLW9mLWNlbnRyYWwtZGlyZWN0b3J5IHJlY29yZDogdGhlIGxhc3Qgb25lLCB3aXRoaW4gdGhlIDY0IEtpQiBhIGNvbW1lbnQgbWF5IHRha2UuICovXG5mdW5jdGlvbiBmaW5kRW9jZCh2aWV3OiBEYXRhVmlldyk6IG51bWJlciB7XG4gIGNvbnN0IHN0b3AgPSBNYXRoLm1heCgwLCB2aWV3LmJ5dGVMZW5ndGggLSAyMiAtIDB4ZmZmZik7XG4gIGZvciAobGV0IGF0ID0gdmlldy5ieXRlTGVuZ3RoIC0gMjI7IGF0ID49IHN0b3A7IGF0LS0pIHtcbiAgICBpZiAodmlldy5nZXRVaW50MzIoYXQsIHRydWUpID09PSBFT0NEKSByZXR1cm4gYXQ7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCd6aXA6IG5vdCBhIHppcCBhcmNoaXZlIChubyBjZW50cmFsIGRpcmVjdG9yeSknKTtcbn1cblxuLyoqIEEgbGl0dGxlLWVuZGlhbiB1NjQgdGhhdCBmaXRzIGEgZG91YmxlIChhcmNoaXZlcyB1bmRlciA4IFBCKS4gKi9cbmZ1bmN0aW9uIG51bSh2aWV3OiBEYXRhVmlldywgYXQ6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB2aWV3LmdldFVpbnQzMihhdCwgdHJ1ZSkgKyB2aWV3LmdldFVpbnQzMihhdCArIDQsIHRydWUpICogMHgxMDAwMDAwMDA7XG59XG5cbmxldCBjcmNUYWJsZTogVWludDMyQXJyYXkgfCBudWxsID0gbnVsbDtcblxuLyoqIENSQy0zMiAoSUVFRSksIGFzIHppcCByZWNvcmRzIGl0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyYzMyKGRhdGE6IFVpbnQ4QXJyYXkpOiBudW1iZXIge1xuICBpZiAoIWNyY1RhYmxlKSB7XG4gICAgY3JjVGFibGUgPSBuZXcgVWludDMyQXJyYXkoMjU2KTtcbiAgICBmb3IgKGxldCBuID0gMDsgbiA8IDI1NjsgbisrKSB7XG4gICAgICBsZXQgYyA9IG47XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IDg7IGsrKykgYyA9IGMgJiAxID8gMHhlZGI4ODMyMCBeIChjID4+PiAxKSA6IGMgPj4+IDE7XG4gICAgICBjcmNUYWJsZVtuXSA9IGMgPj4+IDA7XG4gICAgfVxuICB9XG4gIGxldCBjID0gMHhmZmZmZmZmZjtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSBjID0gY3JjVGFibGVbKGMgXiBkYXRhW2ldKSAmIDB4ZmZdIF4gKGMgPj4+IDgpO1xuICByZXR1cm4gKGMgXiAweGZmZmZmZmZmKSA+Pj4gMDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcGxhdGZvcm1JbmZsYXRlUmF3KGJ5dGVzOiBVaW50OEFycmF5KTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGlmICh0eXBlb2YgRGVjb21wcmVzc2lvblN0cmVhbSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgdGhyb3cgbmV3IEVycm9yKCd6aXA6IGRlZmxhdGVkIG1lbWJlcnMgbmVlZCBEZWNvbXByZXNzaW9uU3RyZWFtJyk7XG4gIGxldCBpbmZsYXRlcjogRGVjb21wcmVzc2lvblN0cmVhbTtcbiAgdHJ5IHtcbiAgICAvLyBDb21wcmVzc2lvbiBTdHJlYW1zJyByYXcgREVGTEFURSAoQ2hyb21lIDEwMywgRmlyZWZveCAxMTMsIFNhZmFyaSAxNi40IG9uKS5cbiAgICBpbmZsYXRlciA9IG5ldyBEZWNvbXByZXNzaW9uU3RyZWFtKCdkZWZsYXRlLXJhdycpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ppcDogdGhpcyBicm93c2VyIGNhbm5vdCBpbmZsYXRlIHppcCBtZW1iZXJzIChubyBEZWNvbXByZXNzaW9uU3RyZWFtIFwiZGVmbGF0ZS1yYXdcIiknKTtcbiAgfVxuICBjb25zdCBzdHJlYW0gPSBuZXcgQmxvYihbYnl0ZXMgYXMgQmxvYlBhcnRdKS5zdHJlYW0oKS5waXBlVGhyb3VnaChpbmZsYXRlcik7XG4gIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCBuZXcgUmVzcG9uc2Uoc3RyZWFtKS5hcnJheUJ1ZmZlcigpKTtcbn1cbiJdfQ==
|