@gmod/bbi 1.0.28 → 1.0.32

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/dist/blockView.js CHANGED
@@ -1,82 +1,148 @@
1
1
  "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (_) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ var __importDefault = (this && this.__importDefault) || function (mod) {
50
+ return (mod && mod.__esModule) ? mod : { "default": mod };
51
+ };
52
+ Object.defineProperty(exports, "__esModule", { value: true });
8
53
  exports.BlockView = void 0;
9
-
10
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
-
12
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
-
14
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
15
-
16
- var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
17
-
18
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
19
-
20
- var _binaryParser = require("@gmod/binary-parser");
21
-
22
- var _abortablePromiseCache = _interopRequireDefault(require("abortable-promise-cache"));
23
-
24
- var _zlib = _interopRequireDefault(require("zlib"));
25
-
26
- var _quickLru = _interopRequireDefault(require("quick-lru"));
27
-
28
- var _range = _interopRequireDefault(require("./range"));
29
-
30
- var _util = require("./util");
31
-
32
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
33
-
34
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
35
-
54
+ var binary_parser_1 = require("@gmod/binary-parser");
55
+ var abortable_promise_cache_1 = __importDefault(require("abortable-promise-cache"));
56
+ var unzip_1 = require("./unzip");
57
+ var quick_lru_1 = __importDefault(require("quick-lru"));
58
+ var range_1 = __importDefault(require("./range"));
59
+ var util_1 = require("./util");
36
60
  var BIG_WIG_TYPE_GRAPH = 1;
37
61
  var BIG_WIG_TYPE_VSTEP = 2;
38
62
  var BIG_WIG_TYPE_FSTEP = 3;
39
-
40
63
  function getParsers(isBigEndian) {
41
- var _choices;
42
-
43
- var le = isBigEndian ? 'big' : 'little';
44
- var summaryParser = new _binaryParser.Parser().endianess(le).uint32('chromId').uint32('start').uint32('end').uint32('validCnt').float('minScore').float('maxScore').float('sumData').float('sumSqData');
45
- var leafParser = new _binaryParser.Parser().endianess(le).uint8('isLeaf').skip(1).uint16('cnt').choice({
46
- tag: 'isLeaf',
47
- choices: {
48
- 1: new _binaryParser.Parser().array('blocksToFetch', {
49
- length: 'cnt',
50
- type: new _binaryParser.Parser().uint32('startChrom').uint32('startBase').uint32('endChrom').uint32('endBase').uint64('blockOffset').uint64('blockSize')
51
- }),
52
- 0: new _binaryParser.Parser().array('recurOffsets', {
53
- length: 'cnt',
54
- type: new _binaryParser.Parser().uint32('startChrom').uint32('startBase').uint32('endChrom').uint32('endBase').uint64('blockOffset')
55
- })
56
- }
57
- });
58
- var bigBedParser = new _binaryParser.Parser().endianess(le).uint32('chromId').int32('start').int32('end').string('rest', {
59
- zeroTerminated: true
60
- });
61
- var bigWigParser = new _binaryParser.Parser().endianess(le).skip(4).int32('blockStart').skip(4).uint32('itemStep').uint32('itemSpan').uint8('blockType').skip(1).uint16('itemCount').choice({
62
- tag: 'blockType',
63
- choices: (_choices = {}, (0, _defineProperty2.default)(_choices, BIG_WIG_TYPE_FSTEP, new _binaryParser.Parser().array('items', {
64
- length: 'itemCount',
65
- type: new _binaryParser.Parser().float('score')
66
- })), (0, _defineProperty2.default)(_choices, BIG_WIG_TYPE_VSTEP, new _binaryParser.Parser().array('items', {
67
- length: 'itemCount',
68
- type: new _binaryParser.Parser().int32('start').float('score')
69
- })), (0, _defineProperty2.default)(_choices, BIG_WIG_TYPE_GRAPH, new _binaryParser.Parser().array('items', {
70
- length: 'itemCount',
71
- type: new _binaryParser.Parser().int32('start').int32('end').float('score')
72
- })), _choices)
73
- });
74
- return {
75
- bigWigParser: bigWigParser,
76
- bigBedParser: bigBedParser,
77
- summaryParser: summaryParser,
78
- leafParser: leafParser
79
- };
64
+ var _a;
65
+ var le = isBigEndian ? 'big' : 'little';
66
+ var summaryParser = new binary_parser_1.Parser()
67
+ .endianess(le)
68
+ .uint32('chromId')
69
+ .uint32('start')
70
+ .uint32('end')
71
+ .uint32('validCnt')
72
+ .float('minScore')
73
+ .float('maxScore')
74
+ .float('sumData')
75
+ .float('sumSqData');
76
+ var leafParser = new binary_parser_1.Parser()
77
+ .endianess(le)
78
+ .uint8('isLeaf')
79
+ .skip(1)
80
+ .uint16('cnt')
81
+ .choice({
82
+ tag: 'isLeaf',
83
+ choices: {
84
+ 1: new binary_parser_1.Parser().array('blocksToFetch', {
85
+ length: 'cnt',
86
+ type: new binary_parser_1.Parser()
87
+ .uint32('startChrom')
88
+ .uint32('startBase')
89
+ .uint32('endChrom')
90
+ .uint32('endBase')
91
+ .uint64('blockOffset')
92
+ .uint64('blockSize'),
93
+ }),
94
+ 0: new binary_parser_1.Parser().array('recurOffsets', {
95
+ length: 'cnt',
96
+ type: new binary_parser_1.Parser()
97
+ .uint32('startChrom')
98
+ .uint32('startBase')
99
+ .uint32('endChrom')
100
+ .uint32('endBase')
101
+ .uint64('blockOffset'),
102
+ }),
103
+ },
104
+ });
105
+ var bigBedParser = new binary_parser_1.Parser()
106
+ .endianess(le)
107
+ .uint32('chromId')
108
+ .int32('start')
109
+ .int32('end')
110
+ .string('rest', {
111
+ zeroTerminated: true,
112
+ });
113
+ var bigWigParser = new binary_parser_1.Parser()
114
+ .endianess(le)
115
+ .skip(4)
116
+ .int32('blockStart')
117
+ .skip(4)
118
+ .uint32('itemStep')
119
+ .uint32('itemSpan')
120
+ .uint8('blockType')
121
+ .skip(1)
122
+ .uint16('itemCount')
123
+ .choice({
124
+ tag: 'blockType',
125
+ choices: (_a = {},
126
+ _a[BIG_WIG_TYPE_FSTEP] = new binary_parser_1.Parser().array('items', {
127
+ length: 'itemCount',
128
+ type: new binary_parser_1.Parser().float('score'),
129
+ }),
130
+ _a[BIG_WIG_TYPE_VSTEP] = new binary_parser_1.Parser().array('items', {
131
+ length: 'itemCount',
132
+ type: new binary_parser_1.Parser().int32('start').float('score'),
133
+ }),
134
+ _a[BIG_WIG_TYPE_GRAPH] = new binary_parser_1.Parser().array('items', {
135
+ length: 'itemCount',
136
+ type: new binary_parser_1.Parser().int32('start').int32('end').float('score'),
137
+ }),
138
+ _a),
139
+ });
140
+ return {
141
+ bigWigParser: bigWigParser,
142
+ bigBedParser: bigBedParser,
143
+ summaryParser: summaryParser,
144
+ leafParser: leafParser,
145
+ };
80
146
  }
81
147
  /**
82
148
  * View into a subset of the data in a BigWig file.
@@ -85,447 +151,275 @@ function getParsers(isBigEndian) {
85
151
  * Explorer by Thomas Down.
86
152
  * @constructs
87
153
  */
88
-
89
-
90
- var BlockView =
91
- /*#__PURE__*/
92
- function () {
93
- function BlockView(bbi, refsByName, cirTreeOffset, cirTreeLength, isBigEndian, isCompressed, blockType) {
94
- (0, _classCallCheck2.default)(this, BlockView);
95
- (0, _defineProperty2.default)(this, "cirTreeOffset", void 0);
96
- (0, _defineProperty2.default)(this, "cirTreeLength", void 0);
97
- (0, _defineProperty2.default)(this, "bbi", void 0);
98
- (0, _defineProperty2.default)(this, "isCompressed", void 0);
99
- (0, _defineProperty2.default)(this, "isBigEndian", void 0);
100
- (0, _defineProperty2.default)(this, "refsByName", void 0);
101
- (0, _defineProperty2.default)(this, "blockType", void 0);
102
- (0, _defineProperty2.default)(this, "cirTreePromise", void 0);
103
- (0, _defineProperty2.default)(this, "featureCache", void 0);
104
- (0, _defineProperty2.default)(this, "leafParser", void 0);
105
- (0, _defineProperty2.default)(this, "bigWigParser", void 0);
106
- (0, _defineProperty2.default)(this, "bigBedParser", void 0);
107
- (0, _defineProperty2.default)(this, "summaryParser", void 0);
108
- if (!(cirTreeOffset >= 0)) throw new Error('invalid cirTreeOffset!');
109
- if (!(cirTreeLength > 0)) throw new Error('invalid cirTreeLength!');
110
- this.cirTreeOffset = cirTreeOffset;
111
- this.cirTreeLength = cirTreeLength;
112
- this.isCompressed = isCompressed;
113
- this.refsByName = refsByName;
114
- this.isBigEndian = isBigEndian;
115
- this.bbi = bbi;
116
- this.blockType = blockType;
117
- Object.assign(this, getParsers(isBigEndian));
118
- this.featureCache = new _abortablePromiseCache.default({
119
- cache: new _quickLru.default({
120
- maxSize: 1000
121
- }),
122
- fill: function () {
123
- var _fill = (0, _asyncToGenerator2.default)(
124
- /*#__PURE__*/
125
- _regenerator.default.mark(function _callee(requestData, signal) {
126
- var length, offset, _ref, buffer;
127
-
128
- return _regenerator.default.wrap(function _callee$(_context) {
129
- while (1) {
130
- switch (_context.prev = _context.next) {
131
- case 0:
132
- length = requestData.length, offset = requestData.offset;
133
- _context.next = 3;
134
- return bbi.read(Buffer.alloc(length), 0, length, offset, {
135
- signal: signal
136
- });
137
-
138
- case 3:
139
- _ref = _context.sent;
140
- buffer = _ref.buffer;
141
- return _context.abrupt("return", buffer);
142
-
143
- case 6:
144
- case "end":
145
- return _context.stop();
146
- }
147
- }
148
- }, _callee);
149
- }));
150
-
151
- function fill(_x, _x2) {
152
- return _fill.apply(this, arguments);
153
- }
154
-
155
- return fill;
156
- }()
157
- });
158
- }
159
-
160
- (0, _createClass2.default)(BlockView, [{
161
- key: "readWigData",
162
- value: function () {
163
- var _readWigData = (0, _asyncToGenerator2.default)(
164
- /*#__PURE__*/
165
- _regenerator.default.mark(function _callee3(chrName, start, end, observer, opts) {
154
+ var BlockView = /** @class */ (function () {
155
+ function BlockView(bbi, refsByName, cirTreeOffset, cirTreeLength, isBigEndian, isCompressed, blockType) {
166
156
  var _this = this;
167
-
168
- var refsByName, bbi, cirTreeOffset, isBigEndian, signal, chrId, request, _ref2, buffer, cirBlockSize, blocksToFetch, outstanding, cirFobRecur2, filterFeats, cirFobStartFetch, cirFobRecur;
169
-
170
- return _regenerator.default.wrap(function _callee3$(_context3) {
171
- while (1) {
172
- switch (_context3.prev = _context3.next) {
173
- case 0:
174
- _context3.prev = 0;
175
- refsByName = this.refsByName, bbi = this.bbi, cirTreeOffset = this.cirTreeOffset, isBigEndian = this.isBigEndian;
176
- signal = opts.signal;
177
- chrId = refsByName[chrName];
178
-
179
- if (chrId === undefined) {
180
- observer.complete();
181
- }
182
-
183
- request = {
184
- chrId: chrId,
185
- start: start,
186
- end: end
187
- };
188
-
189
- if (!this.cirTreePromise) {
190
- this.cirTreePromise = bbi.read(Buffer.alloc(48), 0, 48, cirTreeOffset, {
191
- signal: signal
192
- });
193
- }
194
-
195
- _context3.next = 9;
196
- return this.cirTreePromise;
197
-
198
- case 9:
199
- _ref2 = _context3.sent;
200
- buffer = _ref2.buffer;
201
- cirBlockSize = isBigEndian ? buffer.readUInt32BE(4) : buffer.readUInt32LE(4);
202
- blocksToFetch = [];
203
- outstanding = 0; //eslint-disable-next-line prefer-const
204
-
205
- filterFeats = function filterFeats(b) {
206
- return (b.startChrom < chrId || b.startChrom === chrId && b.startBase <= end) && (b.endChrom > chrId || b.endChrom === chrId && b.endBase >= start);
207
- };
208
-
209
- cirFobStartFetch =
210
- /*#__PURE__*/
211
- function () {
212
- var _ref3 = (0, _asyncToGenerator2.default)(
213
- /*#__PURE__*/
214
- _regenerator.default.mark(function _callee2(off, fr, level) {
215
- var length, offset, resultBuffer, i;
216
- return _regenerator.default.wrap(function _callee2$(_context2) {
217
- while (1) {
218
- switch (_context2.prev = _context2.next) {
219
- case 0:
220
- _context2.prev = 0;
221
- length = fr.max() - fr.min();
222
- offset = fr.min();
223
- _context2.next = 5;
224
- return _this.featureCache.get("".concat(length, "_").concat(offset), {
225
- length: length,
226
- offset: offset
227
- }, signal);
228
-
229
- case 5:
230
- resultBuffer = _context2.sent;
231
-
232
- for (i = 0; i < off.length; i += 1) {
233
- if (fr.contains(off[i])) {
234
- cirFobRecur2(resultBuffer, off[i] - offset, level, observer, opts);
235
- outstanding -= 1;
236
-
237
- if (outstanding === 0) {
238
- _this.readFeatures(observer, blocksToFetch, _objectSpread({}, opts, {
239
- request: request
240
- }));
241
- }
242
- }
243
- }
244
-
245
- _context2.next = 12;
246
- break;
247
-
248
- case 9:
249
- _context2.prev = 9;
250
- _context2.t0 = _context2["catch"](0);
251
- observer.error(_context2.t0);
252
-
253
- case 12:
254
- case "end":
255
- return _context2.stop();
256
- }
257
- }
258
- }, _callee2, null, [[0, 9]]);
259
- }));
260
-
261
- return function cirFobStartFetch(_x8, _x9, _x10) {
262
- return _ref3.apply(this, arguments);
263
- };
264
- }();
265
-
266
- cirFobRecur = function cirFobRecur(offset, level) {
267
- try {
268
- outstanding += offset.length;
269
- var maxCirBlockSpan = 4 + cirBlockSize * 32; // Upper bound on size, based on a completely full leaf node.
270
-
271
- var spans = new _range.default(offset[0], offset[0] + maxCirBlockSpan);
272
-
273
- for (var i = 1; i < offset.length; i += 1) {
274
- var blockSpan = new _range.default(offset[i], offset[i] + maxCirBlockSpan);
275
- spans = spans.union(blockSpan);
157
+ this.featureCache = new abortable_promise_cache_1.default({
158
+ cache: new quick_lru_1.default({ maxSize: 1000 }),
159
+ fill: function (requestData, signal) { return __awaiter(_this, void 0, void 0, function () {
160
+ var length, offset, buffer;
161
+ return __generator(this, function (_a) {
162
+ switch (_a.label) {
163
+ case 0:
164
+ length = requestData.length, offset = requestData.offset;
165
+ return [4 /*yield*/, this.bbi.read(Buffer.alloc(length), 0, length, offset, { signal: signal })];
166
+ case 1:
167
+ buffer = (_a.sent()).buffer;
168
+ return [2 /*return*/, buffer];
276
169
  }
277
-
278
- spans.getRanges().map(function (fr) {
279
- return cirFobStartFetch(offset, fr, level);
280
- });
281
- } catch (e) {
282
- observer.error(e);
283
- }
284
- };
285
-
286
- cirFobRecur2 = function cirFobRecur2(cirBlockData, offset, level) {
287
- try {
288
- var data = cirBlockData.slice(offset);
289
-
290
- var p = _this.leafParser.parse(data).result;
291
-
292
- if (p.blocksToFetch) {
293
- blocksToFetch = blocksToFetch.concat(p.blocksToFetch.filter(filterFeats).map(function (l) {
294
- return {
295
- offset: l.blockOffset,
296
- length: l.blockSize
297
- };
298
- }));
299
- }
300
-
301
- if (p.recurOffsets) {
302
- var recurOffsets = p.recurOffsets.filter(filterFeats).map(function (l) {
303
- return l.blockOffset;
304
- });
305
-
306
- if (recurOffsets.length > 0) {
307
- cirFobRecur(recurOffsets, level + 1);
308
- }
309
- }
310
- } catch (e) {
311
- observer.error(e);
312
- }
313
- };
314
-
315
- return _context3.abrupt("return", cirFobRecur([cirTreeOffset + 48], 1));
316
-
317
- case 21:
318
- _context3.prev = 21;
319
- _context3.t0 = _context3["catch"](0);
320
- observer.error(_context3.t0);
321
-
322
- case 24:
323
- case "end":
324
- return _context3.stop();
325
- }
326
- }
327
- }, _callee3, this, [[0, 21]]);
328
- }));
329
-
330
- function readWigData(_x3, _x4, _x5, _x6, _x7) {
331
- return _readWigData.apply(this, arguments);
332
- }
333
-
334
- return readWigData;
335
- }()
336
- }, {
337
- key: "parseSummaryBlock",
338
- value: function parseSummaryBlock(data, startOffset, request) {
339
- var features = [];
340
- var currOffset = startOffset;
341
-
342
- while (currOffset < data.byteLength) {
343
- var res = this.summaryParser.parse(data.slice(currOffset));
344
- features.push(res.result);
345
- currOffset += res.offset;
346
- }
347
-
348
- var items = features;
349
- if (request) items = items.filter(function (elt) {
350
- return elt.chromId === request.chrId;
351
- });
352
- items = items.map(function (elt) {
353
- return {
354
- start: elt.start,
355
- end: elt.end,
356
- maxScore: elt.maxScore,
357
- minScore: elt.minScore,
358
- score: elt.sumData / (elt.validCnt || 1),
359
- summary: true
360
- };
361
- });
362
- return request ? items.filter(function (f) {
363
- return BlockView.coordFilter(f, request);
364
- }) : items;
365
- }
366
- }, {
367
- key: "parseBigBedBlock",
368
- value: function parseBigBedBlock(data, startOffset, offset, request) {
369
- var items = [];
370
- var currOffset = startOffset;
371
-
372
- while (currOffset < data.byteLength) {
373
- var res = this.bigBedParser.parse(data.slice(currOffset));
374
- res.result.uniqueId = "bb-".concat(offset + currOffset);
375
- items.push(res.result);
376
- currOffset += res.offset;
377
- }
378
-
379
- return request ? items.filter(function (f) {
380
- return BlockView.coordFilter(f, request);
381
- }) : items;
382
- }
383
- }, {
384
- key: "parseBigWigBlock",
385
- value: function parseBigWigBlock(bytes, startOffset, request) {
386
- var data = bytes.slice(startOffset);
387
- var results = this.bigWigParser.parse(data).result;
388
- var items = results.items,
389
- itemSpan = results.itemSpan,
390
- itemStep = results.itemStep,
391
- blockStart = results.blockStart,
392
- blockType = results.blockType;
393
-
394
- if (blockType === BIG_WIG_TYPE_FSTEP) {
395
- for (var i = 0; i < items.length; i++) {
396
- items[i].start = blockStart + i * itemStep;
397
- items[i].end = blockStart + i * itemStep + itemSpan;
170
+ });
171
+ }); },
172
+ });
173
+ if (!(cirTreeOffset >= 0)) {
174
+ throw new Error('invalid cirTreeOffset!');
398
175
  }
399
- } else if (blockType === BIG_WIG_TYPE_VSTEP) {
400
- for (var _i = 0; _i < items.length; _i++) {
401
- items[_i].end = items[_i].start + itemSpan;
176
+ if (!(cirTreeLength > 0)) {
177
+ throw new Error('invalid cirTreeLength!');
402
178
  }
403
- }
404
-
405
- return request ? items.filter(function (f) {
406
- return BlockView.coordFilter(f, request);
407
- }) : items;
179
+ this.cirTreeOffset = cirTreeOffset;
180
+ this.cirTreeLength = cirTreeLength;
181
+ this.isCompressed = isCompressed;
182
+ this.refsByName = refsByName;
183
+ this.isBigEndian = isBigEndian;
184
+ this.bbi = bbi;
185
+ this.blockType = blockType;
186
+ Object.assign(this, getParsers(isBigEndian));
408
187
  }
409
- }, {
410
- key: "readFeatures",
411
- value: function () {
412
- var _readFeatures = (0, _asyncToGenerator2.default)(
413
- /*#__PURE__*/
414
- _regenerator.default.mark(function _callee5(observer, blocks) {
415
- var _this2 = this;
416
-
417
- var opts,
418
- blockType,
419
- isCompressed,
420
- signal,
421
- request,
422
- blockGroupsToFetch,
423
- _args5 = arguments;
424
- return _regenerator.default.wrap(function _callee5$(_context5) {
425
- while (1) {
426
- switch (_context5.prev = _context5.next) {
427
- case 0:
428
- opts = _args5.length > 2 && _args5[2] !== undefined ? _args5[2] : {};
429
- _context5.prev = 1;
430
- blockType = this.blockType, isCompressed = this.isCompressed;
431
- signal = opts.signal, request = opts.request;
432
- blockGroupsToFetch = (0, _util.groupBlocks)(blocks);
433
- (0, _util.checkAbortSignal)(signal);
434
- _context5.next = 8;
435
- return Promise.all(blockGroupsToFetch.map(
436
- /*#__PURE__*/
437
- function () {
438
- var _ref4 = (0, _asyncToGenerator2.default)(
439
- /*#__PURE__*/
440
- _regenerator.default.mark(function _callee4(blockGroup) {
441
- var length, offset, data;
442
- return _regenerator.default.wrap(function _callee4$(_context4) {
443
- while (1) {
444
- switch (_context4.prev = _context4.next) {
445
- case 0:
446
- (0, _util.checkAbortSignal)(signal);
447
- length = blockGroup.length, offset = blockGroup.offset;
448
- _context4.next = 4;
449
- return _this2.featureCache.get("".concat(length, "_").concat(offset), blockGroup, signal);
450
-
451
- case 4:
452
- data = _context4.sent;
453
- blockGroup.blocks.forEach(function (block) {
454
- (0, _util.checkAbortSignal)(signal);
455
- var blockOffset = block.offset - blockGroup.offset;
456
- var resultData = data;
457
-
458
- if (isCompressed) {
459
- resultData = _zlib.default.inflateSync(data.slice(blockOffset));
460
- blockOffset = 0;
461
- }
462
-
463
- (0, _util.checkAbortSignal)(signal);
464
-
465
- switch (blockType) {
466
- case 'summary':
467
- observer.next(_this2.parseSummaryBlock(resultData, blockOffset, request));
468
- break;
469
-
470
- case 'bigwig':
471
- observer.next(_this2.parseBigWigBlock(resultData, blockOffset, request));
472
- break;
473
-
474
- case 'bigbed':
475
- // eslint-disable-next-line no-bitwise
476
- observer.next(_this2.parseBigBedBlock(resultData, blockOffset, block.offset * (1 << 8), request));
477
- break;
478
-
479
- default:
480
- console.warn("Don't know what to do with ".concat(blockType));
481
- }
188
+ BlockView.prototype.readWigData = function (chrName, start, end, observer, opts) {
189
+ return __awaiter(this, void 0, void 0, function () {
190
+ var _a, refsByName, bbi, cirTreeOffset, isBigEndian, signal_1, chrId_1, request_1, buffer, cirBlockSize_1, blocksToFetch_1, outstanding_1, cirFobRecur2_1, filterFeats_1, cirFobStartFetch_1, cirFobRecur_1, e_1;
191
+ var _this = this;
192
+ return __generator(this, function (_b) {
193
+ switch (_b.label) {
194
+ case 0:
195
+ _b.trys.push([0, 2, , 3]);
196
+ _a = this, refsByName = _a.refsByName, bbi = _a.bbi, cirTreeOffset = _a.cirTreeOffset, isBigEndian = _a.isBigEndian;
197
+ signal_1 = opts.signal;
198
+ chrId_1 = refsByName[chrName];
199
+ if (chrId_1 === undefined) {
200
+ observer.complete();
201
+ }
202
+ request_1 = { chrId: chrId_1, start: start, end: end };
203
+ if (!this.cirTreePromise) {
204
+ this.cirTreePromise = bbi.read(Buffer.alloc(48), 0, 48, cirTreeOffset, {
205
+ signal: signal_1,
482
206
  });
483
-
484
- case 6:
485
- case "end":
486
- return _context4.stop();
487
207
  }
488
- }
489
- }, _callee4);
490
- }));
491
-
492
- return function (_x13) {
493
- return _ref4.apply(this, arguments);
494
- };
495
- }()));
496
-
497
- case 8:
498
- observer.complete();
499
- _context5.next = 14;
500
- break;
501
-
502
- case 11:
503
- _context5.prev = 11;
504
- _context5.t0 = _context5["catch"](1);
505
- observer.error(_context5.t0);
506
-
507
- case 14:
508
- case "end":
509
- return _context5.stop();
208
+ return [4 /*yield*/, this.cirTreePromise];
209
+ case 1:
210
+ buffer = (_b.sent()).buffer;
211
+ cirBlockSize_1 = isBigEndian
212
+ ? buffer.readUInt32BE(4)
213
+ : buffer.readUInt32LE(4);
214
+ blocksToFetch_1 = [];
215
+ outstanding_1 = 0;
216
+ cirFobRecur2_1 = function (cirBlockData, offset, level) {
217
+ try {
218
+ var data = cirBlockData.slice(offset);
219
+ var p = _this.leafParser.parse(data).result;
220
+ if (p.blocksToFetch) {
221
+ blocksToFetch_1 = blocksToFetch_1.concat(p.blocksToFetch.filter(filterFeats_1).map(function (l) { return ({
222
+ offset: l.blockOffset,
223
+ length: l.blockSize,
224
+ }); }));
225
+ }
226
+ if (p.recurOffsets) {
227
+ var recurOffsets = p.recurOffsets
228
+ .filter(filterFeats_1)
229
+ .map(function (l) { return l.blockOffset; });
230
+ if (recurOffsets.length > 0) {
231
+ cirFobRecur_1(recurOffsets, level + 1);
232
+ }
233
+ }
234
+ }
235
+ catch (e) {
236
+ observer.error(e);
237
+ }
238
+ };
239
+ filterFeats_1 = function (b) {
240
+ var startChrom = b.startChrom, startBase = b.startBase, endChrom = b.endChrom, endBase = b.endBase;
241
+ return ((startChrom < chrId_1 || (startChrom === chrId_1 && startBase <= end)) &&
242
+ (endChrom > chrId_1 || (endChrom === chrId_1 && endBase >= start)));
243
+ };
244
+ cirFobStartFetch_1 = function (off, fr, level) { return __awaiter(_this, void 0, void 0, function () {
245
+ var length_1, offset, resultBuffer, i, e_2;
246
+ return __generator(this, function (_a) {
247
+ switch (_a.label) {
248
+ case 0:
249
+ _a.trys.push([0, 2, , 3]);
250
+ length_1 = fr.max() - fr.min();
251
+ offset = fr.min();
252
+ return [4 /*yield*/, this.featureCache.get("".concat(length_1, "_").concat(offset), { length: length_1, offset: offset }, signal_1)];
253
+ case 1:
254
+ resultBuffer = _a.sent();
255
+ for (i = 0; i < off.length; i += 1) {
256
+ if (fr.contains(off[i])) {
257
+ cirFobRecur2_1(resultBuffer, off[i] - offset, level);
258
+ outstanding_1 -= 1;
259
+ if (outstanding_1 === 0) {
260
+ this.readFeatures(observer, blocksToFetch_1, __assign(__assign({}, opts), { request: request_1 }));
261
+ }
262
+ }
263
+ }
264
+ return [3 /*break*/, 3];
265
+ case 2:
266
+ e_2 = _a.sent();
267
+ observer.error(e_2);
268
+ return [3 /*break*/, 3];
269
+ case 3: return [2 /*return*/];
270
+ }
271
+ });
272
+ }); };
273
+ cirFobRecur_1 = function (offset, level) {
274
+ try {
275
+ outstanding_1 += offset.length;
276
+ var maxCirBlockSpan = 4 + cirBlockSize_1 * 32; // Upper bound on size, based on a completely full leaf node.
277
+ var spans = new range_1.default(offset[0], offset[0] + maxCirBlockSpan);
278
+ for (var i = 1; i < offset.length; i += 1) {
279
+ var blockSpan = new range_1.default(offset[i], offset[i] + maxCirBlockSpan);
280
+ spans = spans.union(blockSpan);
281
+ }
282
+ spans.getRanges().map(function (fr) { return cirFobStartFetch_1(offset, fr, level); });
283
+ }
284
+ catch (e) {
285
+ observer.error(e);
286
+ }
287
+ };
288
+ return [2 /*return*/, cirFobRecur_1([cirTreeOffset + 48], 1)];
289
+ case 2:
290
+ e_1 = _b.sent();
291
+ observer.error(e_1);
292
+ return [3 /*break*/, 3];
293
+ case 3: return [2 /*return*/];
294
+ }
295
+ });
296
+ });
297
+ };
298
+ BlockView.prototype.parseSummaryBlock = function (data, startOffset, request) {
299
+ var features = [];
300
+ var currOffset = startOffset;
301
+ while (currOffset < data.byteLength) {
302
+ var res = this.summaryParser.parse(data.slice(currOffset));
303
+ features.push(res.result);
304
+ currOffset += res.offset;
305
+ }
306
+ var items = features;
307
+ if (request) {
308
+ items = items.filter(function (elt) { return elt.chromId === request.chrId; });
309
+ }
310
+ var feats = items.map(function (elt) { return ({
311
+ start: elt.start,
312
+ end: elt.end,
313
+ maxScore: elt.maxScore,
314
+ minScore: elt.minScore,
315
+ score: elt.sumData / (elt.validCnt || 1),
316
+ summary: true,
317
+ }); });
318
+ return request
319
+ ? feats.filter(function (f) { return BlockView.coordFilter(f, request); })
320
+ : feats;
321
+ };
322
+ BlockView.prototype.parseBigBedBlock = function (data, startOffset, offset, request) {
323
+ var items = [];
324
+ var currOffset = startOffset;
325
+ while (currOffset < data.byteLength) {
326
+ var res = this.bigBedParser.parse(data.slice(currOffset));
327
+ res.result.uniqueId = "bb-".concat(offset + currOffset);
328
+ items.push(res.result);
329
+ currOffset += res.offset;
330
+ }
331
+ return request
332
+ ? items.filter(function (f) { return BlockView.coordFilter(f, request); })
333
+ : items;
334
+ };
335
+ BlockView.prototype.parseBigWigBlock = function (bytes, startOffset, request) {
336
+ var data = bytes.slice(startOffset);
337
+ var results = this.bigWigParser.parse(data).result;
338
+ var items = results.items, itemSpan = results.itemSpan, itemStep = results.itemStep, blockStart = results.blockStart, blockType = results.blockType;
339
+ if (blockType === BIG_WIG_TYPE_FSTEP) {
340
+ for (var i = 0; i < items.length; i++) {
341
+ items[i].start = blockStart + i * itemStep;
342
+ items[i].end = blockStart + i * itemStep + itemSpan;
510
343
  }
511
- }
512
- }, _callee5, this, [[1, 11]]);
513
- }));
514
-
515
- function readFeatures(_x11, _x12) {
516
- return _readFeatures.apply(this, arguments);
517
- }
518
-
519
- return readFeatures;
520
- }()
521
- }], [{
522
- key: "coordFilter",
523
- value: function coordFilter(f, range) {
524
- return f.start < range.end && f.end >= range.start;
525
- }
526
- }]);
527
- return BlockView;
528
- }();
529
-
344
+ }
345
+ else if (blockType === BIG_WIG_TYPE_VSTEP) {
346
+ for (var i = 0; i < items.length; i++) {
347
+ items[i].end = items[i].start + itemSpan;
348
+ }
349
+ }
350
+ return request
351
+ ? items.filter(function (f) { return BlockView.coordFilter(f, request); })
352
+ : items;
353
+ };
354
+ BlockView.coordFilter = function (f, range) {
355
+ return f.start < range.end && f.end >= range.start;
356
+ };
357
+ BlockView.prototype.readFeatures = function (observer, blocks, opts) {
358
+ if (opts === void 0) { opts = {}; }
359
+ return __awaiter(this, void 0, void 0, function () {
360
+ var _a, blockType_1, isCompressed_1, signal_2, request_2, blockGroupsToFetch, e_3;
361
+ var _this = this;
362
+ return __generator(this, function (_b) {
363
+ switch (_b.label) {
364
+ case 0:
365
+ _b.trys.push([0, 2, , 3]);
366
+ _a = this, blockType_1 = _a.blockType, isCompressed_1 = _a.isCompressed;
367
+ signal_2 = opts.signal, request_2 = opts.request;
368
+ blockGroupsToFetch = (0, util_1.groupBlocks)(blocks);
369
+ (0, util_1.checkAbortSignal)(signal_2);
370
+ return [4 /*yield*/, Promise.all(blockGroupsToFetch.map(function (blockGroup) { return __awaiter(_this, void 0, void 0, function () {
371
+ var length, offset, data;
372
+ var _this = this;
373
+ return __generator(this, function (_a) {
374
+ switch (_a.label) {
375
+ case 0:
376
+ (0, util_1.checkAbortSignal)(signal_2);
377
+ length = blockGroup.length, offset = blockGroup.offset;
378
+ return [4 /*yield*/, this.featureCache.get("".concat(length, "_").concat(offset), blockGroup, signal_2)];
379
+ case 1:
380
+ data = _a.sent();
381
+ blockGroup.blocks.forEach(function (block) {
382
+ (0, util_1.checkAbortSignal)(signal_2);
383
+ var blockOffset = block.offset - blockGroup.offset;
384
+ var resultData = data;
385
+ if (isCompressed_1) {
386
+ resultData = (0, unzip_1.unzip)(data.slice(blockOffset));
387
+ blockOffset = 0;
388
+ }
389
+ (0, util_1.checkAbortSignal)(signal_2);
390
+ switch (blockType_1) {
391
+ case 'summary':
392
+ observer.next(_this.parseSummaryBlock(resultData, blockOffset, request_2));
393
+ break;
394
+ case 'bigwig':
395
+ observer.next(_this.parseBigWigBlock(resultData, blockOffset, request_2));
396
+ break;
397
+ case 'bigbed':
398
+ observer.next(_this.parseBigBedBlock(resultData, blockOffset,
399
+ // eslint-disable-next-line no-bitwise
400
+ block.offset * (1 << 8), request_2));
401
+ break;
402
+ default:
403
+ console.warn("Don't know what to do with ".concat(blockType_1));
404
+ }
405
+ });
406
+ return [2 /*return*/];
407
+ }
408
+ });
409
+ }); }))];
410
+ case 1:
411
+ _b.sent();
412
+ observer.complete();
413
+ return [3 /*break*/, 3];
414
+ case 2:
415
+ e_3 = _b.sent();
416
+ observer.error(e_3);
417
+ return [3 /*break*/, 3];
418
+ case 3: return [2 /*return*/];
419
+ }
420
+ });
421
+ });
422
+ };
423
+ return BlockView;
424
+ }());
530
425
  exports.BlockView = BlockView;
531
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9ibG9ja1ZpZXcudHMiXSwibmFtZXMiOlsiQklHX1dJR19UWVBFX0dSQVBIIiwiQklHX1dJR19UWVBFX1ZTVEVQIiwiQklHX1dJR19UWVBFX0ZTVEVQIiwiZ2V0UGFyc2VycyIsImlzQmlnRW5kaWFuIiwibGUiLCJzdW1tYXJ5UGFyc2VyIiwiUGFyc2VyIiwiZW5kaWFuZXNzIiwidWludDMyIiwiZmxvYXQiLCJsZWFmUGFyc2VyIiwidWludDgiLCJza2lwIiwidWludDE2IiwiY2hvaWNlIiwidGFnIiwiY2hvaWNlcyIsImFycmF5IiwibGVuZ3RoIiwidHlwZSIsInVpbnQ2NCIsImJpZ0JlZFBhcnNlciIsImludDMyIiwic3RyaW5nIiwiemVyb1Rlcm1pbmF0ZWQiLCJiaWdXaWdQYXJzZXIiLCJCbG9ja1ZpZXciLCJiYmkiLCJyZWZzQnlOYW1lIiwiY2lyVHJlZU9mZnNldCIsImNpclRyZWVMZW5ndGgiLCJpc0NvbXByZXNzZWQiLCJibG9ja1R5cGUiLCJFcnJvciIsIk9iamVjdCIsImFzc2lnbiIsImZlYXR1cmVDYWNoZSIsIkFib3J0YWJsZVByb21pc2VDYWNoZSIsImNhY2hlIiwiUXVpY2tMUlUiLCJtYXhTaXplIiwiZmlsbCIsInJlcXVlc3REYXRhIiwic2lnbmFsIiwib2Zmc2V0IiwicmVhZCIsIkJ1ZmZlciIsImFsbG9jIiwiYnVmZmVyIiwiY2hyTmFtZSIsInN0YXJ0IiwiZW5kIiwib2JzZXJ2ZXIiLCJvcHRzIiwiY2hySWQiLCJ1bmRlZmluZWQiLCJjb21wbGV0ZSIsInJlcXVlc3QiLCJjaXJUcmVlUHJvbWlzZSIsImNpckJsb2NrU2l6ZSIsInJlYWRVSW50MzJCRSIsInJlYWRVSW50MzJMRSIsImJsb2Nrc1RvRmV0Y2giLCJvdXRzdGFuZGluZyIsImZpbHRlckZlYXRzIiwiYiIsInN0YXJ0Q2hyb20iLCJzdGFydEJhc2UiLCJlbmRDaHJvbSIsImVuZEJhc2UiLCJjaXJGb2JTdGFydEZldGNoIiwib2ZmIiwiZnIiLCJsZXZlbCIsIm1heCIsIm1pbiIsImdldCIsInJlc3VsdEJ1ZmZlciIsImkiLCJjb250YWlucyIsImNpckZvYlJlY3VyMiIsInJlYWRGZWF0dXJlcyIsImVycm9yIiwiY2lyRm9iUmVjdXIiLCJtYXhDaXJCbG9ja1NwYW4iLCJzcGFucyIsIlJhbmdlIiwiYmxvY2tTcGFuIiwidW5pb24iLCJnZXRSYW5nZXMiLCJtYXAiLCJlIiwiY2lyQmxvY2tEYXRhIiwiZGF0YSIsInNsaWNlIiwicCIsInBhcnNlIiwicmVzdWx0IiwiY29uY2F0IiwiZmlsdGVyIiwibCIsImJsb2NrT2Zmc2V0IiwiYmxvY2tTaXplIiwicmVjdXJPZmZzZXRzIiwic3RhcnRPZmZzZXQiLCJmZWF0dXJlcyIsImN1cnJPZmZzZXQiLCJieXRlTGVuZ3RoIiwicmVzIiwicHVzaCIsIml0ZW1zIiwiZWx0IiwiY2hyb21JZCIsIm1heFNjb3JlIiwibWluU2NvcmUiLCJzY29yZSIsInN1bURhdGEiLCJ2YWxpZENudCIsInN1bW1hcnkiLCJmIiwiY29vcmRGaWx0ZXIiLCJ1bmlxdWVJZCIsImJ5dGVzIiwicmVzdWx0cyIsIml0ZW1TcGFuIiwiaXRlbVN0ZXAiLCJibG9ja1N0YXJ0IiwiYmxvY2tzIiwiYmxvY2tHcm91cHNUb0ZldGNoIiwiUHJvbWlzZSIsImFsbCIsImJsb2NrR3JvdXAiLCJmb3JFYWNoIiwiYmxvY2siLCJyZXN1bHREYXRhIiwiemxpYiIsImluZmxhdGVTeW5jIiwibmV4dCIsInBhcnNlU3VtbWFyeUJsb2NrIiwicGFyc2VCaWdXaWdCbG9jayIsInBhcnNlQmlnQmVkQmxvY2siLCJjb25zb2xlIiwid2FybiIsInJhbmdlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUE7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBRUE7O0FBQ0E7Ozs7OztBQXNDQSxJQUFNQSxrQkFBa0IsR0FBRyxDQUEzQjtBQUNBLElBQU1DLGtCQUFrQixHQUFHLENBQTNCO0FBQ0EsSUFBTUMsa0JBQWtCLEdBQUcsQ0FBM0I7O0FBRUEsU0FBU0MsVUFBVCxDQUFv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QUYsSUFBUzRGLEtBQUssQ0FBQzdGLEtBQTdDO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQgbm8tYml0d2lzZTogW1wiZXJyb3JcIiwgeyBcImFsbG93XCI6IFtcInxcIl0gfV0gKi9cbmltcG9ydCB7IE9ic2VydmVyIH0gZnJvbSAncnhqcydcbmltcG9ydCB7IFBhcnNlciB9IGZyb20gJ0BnbW9kL2JpbmFyeS1wYXJzZXInXG5pbXBvcnQgQWJvcnRhYmxlUHJvbWlzZUNhY2hlIGZyb20gJ2Fib3J0YWJsZS1wcm9taXNlLWNhY2hlJ1xuaW1wb3J0IHsgR2VuZXJpY0ZpbGVoYW5kbGUgfSBmcm9tICdnZW5lcmljLWZpbGVoYW5kbGUnXG5pbXBvcnQgemxpYiBmcm9tICd6bGliJ1xuaW1wb3J0IFF1aWNrTFJVIGZyb20gJ3F1aWNrLWxydSdcbmltcG9ydCB7IEZlYXR1cmUgfSBmcm9tICcuL2JiaSdcbmltcG9ydCBSYW5nZSBmcm9tICcuL3JhbmdlJ1xuaW1wb3J0IHsgZ3JvdXBCbG9ja3MsIGNoZWNrQWJvcnRTaWduYWwgfSBmcm9tICcuL3V0aWwnXG5cbmludGVyZmFjZSBDb29yZFJlcXVlc3Qge1xuICBjaHJJZDogbnVtYmVyXG4gIHN0YXJ0OiBudW1iZXJcbiAgZW5kOiBudW1iZXJcbn1cbmludGVyZmFjZSBEYXRhQmxvY2sge1xuICBzdGFydENocm9tOiBudW1iZXJcbiAgZW5kQ2hyb206IG51bWJlclxuICBzdGFydEJhc2U6IG51bWJlclxuICBlbmRCYXNlOiBudW1iZXJcbiAgdmFsaWRDbnQ6IG51bWJlclxuICBtaW5WYWw6IG51bWJlclxuICBtYXhWYWw6IG51bWJlclxuICBzdW1EYXRhOiBudW1iZXJcbiAgc3VtU3FEYXRhOiBudW1iZXJcbn1cbmludGVyZmFjZSBSZWFkRGF0YSB7XG4gIG9mZnNldDogbnVtYmVyXG4gIGxlbmd0aDogbnVtYmVyXG59XG5cbmludGVyZmFjZSBTdW1tYXJ5QmxvY2sge1xuICBjaHJvbUlkOiBudW1iZXJcbiAgc3RhcnQ6IG51bWJlclxuICBlbmQ6IG51bWJlclxuICB2YWxpZENudDogbnVtYmVyXG4gIG1pblNjb3JlOiBudW1iZXJcbiAgbWF4U2NvcmU6IG51bWJlclxuICBzdW1EYXRhOiBudW1iZXJcbiAgc3VtU3FEYXRhOiBudW1iZXJcbn1cbmludGVyZmFjZSBPcHRpb25zIHtcbiAgc2lnbmFsPzogQWJvcnRTaWduYWxcbiAgcmVxdWVzdD86IENvb3JkUmVxdWVzdFxufVxuXG5jb25zdCBCSUdfV0lHX1RZUEVfR1JBUEggPSAxXG5jb25zdCBCSUdfV0lHX1RZUEVfVlNURVAgPSAyXG5jb25zdCBCSUdfV0lHX1RZUEVfRlNURVAgPSAzXG5cbmZ1bmN0aW9uIGdldFBhcnNlcnMoaXNCaWdFbmRpYW46IGJvb2xlYW4pOiBhbnkge1xuICBjb25zdCBsZSA9IGlzQmlnRW5kaWFuID8gJ2JpZycgOiAnbGl0dGxlJ1xuICBjb25zdCBzdW1tYXJ5UGFyc2VyID0gbmV3IFBhcnNlcigpXG4gICAgLmVuZGlhbmVzcyhsZSlcbiAgICAudWludDMyKCdjaHJvbUlkJylcbiAgICAudWludDMyKCdzdGFydCcpXG4gICAgLnVpbnQzMignZW5kJylcbiAgICAudWludDMyKCd2YWxpZENudCcpXG4gICAgLmZsb2F0KCdtaW5TY29yZScpXG4gICAgLmZsb2F0KCdtYXhTY29yZScpXG4gICAgLmZsb2F0KCdzdW1EYXRhJylcbiAgICAuZmxvYXQoJ3N1bVNxRGF0YScpXG5cbiAgY29uc3QgbGVhZlBhcnNlciA9IG5ldyBQYXJzZXIoKVxuICAgIC5lbmRpYW5lc3MobGUpXG4gICAgLnVpbnQ4KCdpc0xlYWYnKVxuICAgIC5za2lwKDEpXG4gICAgLnVpbnQxNignY250JylcbiAgICAuY2hvaWNlKHtcbiAgICAgIHRhZzogJ2lzTGVhZicsXG4gICAgICBjaG9pY2VzOiB7XG4gICAgICAgIDE6IG5ldyBQYXJzZXIoKS5hcnJheSgnYmxvY2tzVG9GZXRjaCcsIHtcbiAgICAgICAgICBsZW5ndGg6ICdjbnQnLFxuICAgICAgICAgIHR5cGU6IG5ldyBQYXJzZXIoKVxuICAgICAgICAgICAgLnVpbnQzMignc3RhcnRDaHJvbScpXG4gICAgICAgICAgICAudWludDMyKCdzdGFydEJhc2UnKVxuICAgICAgICAgICAgLnVpbnQzMignZW5kQ2hyb20nKVxuICAgICAgICAgICAgLnVpbnQzMignZW5kQmFzZScpXG4gICAgICAgICAgICAudWludDY0KCdibG9ja09mZnNldCcpXG4gICAgICAgICAgICAudWludDY0KCdibG9ja1NpemUnKSxcbiAgICAgICAgfSksXG4gICAgICAgIDA6IG5ldyBQYXJzZXIoKS5hcnJheSgncmVjdXJPZmZzZXRzJywge1xuICAgICAgICAgIGxlbmd0aDogJ2NudCcsXG4gICAgICAgICAgdHlwZTogbmV3IFBhcnNlcigpXG4gICAgICAgICAgICAudWludDMyKCdzdGFydENocm9tJylcbiAgICAgICAgICAgIC51aW50MzIoJ3N0YXJ0QmFzZScpXG4gICAgICAgICAgICAudWludDMyKCdlbmRDaHJvbScpXG4gICAgICAgICAgICAudWludDMyKCdlbmRCYXNlJylcbiAgICAgICAgICAgIC51aW50NjQoJ2Jsb2NrT2Zmc2V0JyksXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KVxuICBjb25zdCBiaWdCZWRQYXJzZXIgPSBuZXcgUGFyc2VyKClcbiAgICAuZW5kaWFuZXNzKGxlKVxuICAgIC51aW50MzIoJ2Nocm9tSWQnKVxuICAgIC5pbnQzMignc3RhcnQnKVxuICAgIC5pbnQzMignZW5kJylcbiAgICAuc3RyaW5nKCdyZXN0Jywge1xuICAgICAgemVyb1Rlcm1pbmF0ZWQ6IHRydWUsXG4gICAgfSlcblxuICBjb25zdCBiaWdXaWdQYXJzZXIgPSBuZXcgUGFyc2VyKClcbiAgICAuZW5kaWFuZXNzKGxlKVxuICAgIC5za2lwKDQpXG4gICAgLmludDMyKCdibG9ja1N0YXJ0JylcbiAgICAuc2tpcCg0KVxuICAgIC51aW50MzIoJ2l0ZW1TdGVwJylcbiAgICAudWludDMyKCdpdGVtU3BhbicpXG4gICAgLnVpbnQ4KCdibG9ja1R5cGUnKVxuICAgIC5za2lwKDEpXG4gICAgLnVpbnQxNignaXRlbUNvdW50JylcbiAgICAuY2hvaWNlKHtcbiAgICAgIHRhZzogJ2Jsb2NrVHlwZScsXG4gICAgICBjaG9pY2VzOiB7XG4gICAgICAgIFtCSUdfV0lHX1RZUEVfRlNURVBdOiBuZXcgUGFyc2VyKCkuYXJyYXkoJ2l0ZW1zJywge1xuICAgICAgICAgIGxlbmd0aDogJ2l0ZW1Db3VudCcsXG4gICAgICAgICAgdHlwZTogbmV3IFBhcnNlcigpLmZsb2F0KCdzY29yZScpLFxuICAgICAgICB9KSxcbiAgICAgICAgW0JJR19XSUdfVFlQRV9WU1RFUF06IG5ldyBQYXJzZXIoKS5hcnJheSgnaXRlbXMnLCB7XG4gICAgICAgICAgbGVuZ3RoOiAnaXRlbUNvdW50JyxcbiAgICAgICAgICB0eXBlOiBuZXcgUGFyc2VyKCkuaW50MzIoJ3N0YXJ0JykuZmxvYXQoJ3Njb3JlJyksXG4gICAgICAgIH0pLFxuICAgICAgICBbQklHX1dJR19UWVBFX0dSQVBIXTogbmV3IFBhcnNlcigpLmFycmF5KCdpdGVtcycsIHtcbiAgICAgICAgICBsZW5ndGg6ICdpdGVtQ291bnQnLFxuICAgICAgICAgIHR5cGU6IG5ldyBQYXJzZXIoKVxuICAgICAgICAgICAgLmludDMyKCdzdGFydCcpXG4gICAgICAgICAgICAuaW50MzIoJ2VuZCcpXG4gICAgICAgICAgICAuZmxvYXQoJ3Njb3JlJyksXG4gICAgICAgIH0pLFxuICAgICAgfSxcbiAgICB9KVxuICByZXR1cm4ge1xuICAgIGJpZ1dpZ1BhcnNlcixcbiAgICBiaWdCZWRQYXJzZXIsXG4gICAgc3VtbWFyeVBhcnNlcixcbiAgICBsZWFmUGFyc2VyLFxuICB9XG59XG5cbi8qKlxuICogVmlldyBpbnRvIGEgc3Vic2V0IG9mIHRoZSBkYXRhIGluIGEgQmlnV2lnIGZpbGUuXG4gKlxuICogQWRhcHRlZCBieSBSb2JlcnQgQnVlbHMgYW5kIENvbGluIERpZXNoIGZyb20gYmlnd2lnLmpzIGluIHRoZSBEYWxsaWFuY2UgR2Vub21lXG4gKiBFeHBsb3JlciBieSBUaG9tYXMgRG93bi5cbiAqIEBjb25zdHJ1Y3RzXG4gKi9cblxuZXhwb3J0IGNsYXNzIEJsb2NrVmlldyB7XG4gIHByaXZhdGUgY2lyVHJlZU9mZnNldDogbnVtYmVyXG5cbiAgcHJpdmF0ZSBjaXJUcmVlTGVuZ3RoOiBudW1iZXJcblxuICBwcml2YXRlIGJiaTogR2VuZXJpY0ZpbGVoYW5kbGVcblxuICBwcml2YXRlIGlzQ29tcHJlc3NlZDogYm9vbGVhblxuXG4gIHByaXZhdGUgaXNCaWdFbmRpYW46IGJvb2xlYW5cblxuICBwcml2YXRlIHJlZnNCeU5hbWU6IGFueVxuXG4gIHByaXZhdGUgYmxvY2tUeXBlOiBzdHJpbmdcblxuICBwcml2YXRlIGNpclRyZWVQcm9taXNlPzogUHJvbWlzZTx7IGJ5dGVzUmVhZDogbnVtYmVyOyBidWZmZXI6IEJ1ZmZlciB9PlxuXG4gIHByaXZhdGUgZmVhdHVyZUNhY2hlOiBhbnlcblxuICBwcml2YXRlIGxlYWZQYXJzZXI6IGFueVxuXG4gIHByaXZhdGUgYmlnV2lnUGFyc2VyOiBhbnlcblxuICBwcml2YXRlIGJpZ0JlZFBhcnNlcjogYW55XG5cbiAgcHJpdmF0ZSBzdW1tYXJ5UGFyc2VyOiBhbnlcblxuICBwdWJsaWMgY29uc3RydWN0b3IoXG4gICAgYmJpOiBhbnksXG4gICAgcmVmc0J5TmFtZTogYW55LFxuICAgIGNpclRyZWVPZmZzZXQ6IG51bWJlcixcbiAgICBjaXJUcmVlTGVuZ3RoOiBudW1iZXIsXG4gICAgaXNCaWdFbmRpYW46IGJvb2xlYW4sXG4gICAgaXNDb21wcmVzc2VkOiBib29sZWFuLFxuICAgIGJsb2NrVHlwZTogc3RyaW5nLFxuICApIHtcbiAgICBpZiAoIShjaXJUcmVlT2Zmc2V0ID49IDApKSB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgY2lyVHJlZU9mZnNldCEnKVxuICAgIGlmICghKGNpclRyZWVMZW5ndGggPiAwKSkgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGNpclRyZWVMZW5ndGghJylcblxuICAgIHRoaXMuY2lyVHJlZU9mZnNldCA9IGNpclRyZWVPZmZzZXRcbiAgICB0aGlzLmNpclRyZWVMZW5ndGggPSBjaXJUcmVlTGVuZ3RoXG4gICAgdGhpcy5pc0NvbXByZXNzZWQgPSBpc0NvbXByZXNzZWRcbiAgICB0aGlzLnJlZnNCeU5hbWUgPSByZWZzQnlOYW1lXG4gICAgdGhpcy5pc0JpZ0VuZGlhbiA9IGlzQmlnRW5kaWFuXG4gICAgdGhpcy5iYmkgPSBiYmlcbiAgICB0aGlzLmJsb2NrVHlwZSA9IGJsb2NrVHlwZVxuICAgIE9iamVjdC5hc3NpZ24odGhpcywgZ2V0UGFyc2Vycyhpc0JpZ0VuZGlhbikpXG5cbiAgICB0aGlzLmZlYXR1cmVDYWNoZSA9IG5ldyBBYm9ydGFibGVQcm9taXNlQ2FjaGUoe1xuICAgICAgY2FjaGU6IG5ldyBRdWlja0xSVSh7IG1heFNpemU6IDEwMDAgfSksXG5cbiAgICAgIGFzeW5jIGZpbGwocmVxdWVzdERhdGE6IFJlYWREYXRhLCBzaWduYWw6IEFib3J0U2lnbmFsKSB7XG4gICAgICAgIGNvbnN0IHsgbGVuZ3RoLCBvZmZzZXQgfSA9IHJlcXVlc3REYXRhXG4gICAgICAgIGNvbnN0IHsgYnVmZmVyIH0gPSBhd2FpdCBiYmkucmVhZChCdWZmZXIuYWxsb2MobGVuZ3RoKSwgMCwgbGVuZ3RoLCBvZmZzZXQsIHsgc2lnbmFsIH0pXG4gICAgICAgIHJldHVybiBidWZmZXJcbiAgICAgIH0sXG4gICAgfSlcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZWFkV2lnRGF0YShcbiAgICBjaHJOYW1lOiBzdHJpbmcsXG4gICAgc3RhcnQ6IG51bWJlcixcbiAgICBlbmQ6IG51bWJlcixcbiAgICBvYnNlcnZlcjogT2JzZXJ2ZXI8RmVhdHVyZVtdPixcbiAgICBvcHRzOiBPcHRpb25zLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyByZWZzQnlOYW1lLCBiYmksIGNpclRyZWVPZmZzZXQsIGlzQmlnRW5kaWFuIH0gPSB0aGlzXG4gICAgICBjb25zdCB7IHNpZ25hbCB9ID0gb3B0c1xuICAgICAgY29uc3QgY2hySWQgPSByZWZzQnlOYW1lW2Nock5hbWVdXG4gICAgICBpZiAoY2hySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpXG4gICAgICB9XG4gICAgICBjb25zdCByZXF1ZXN0ID0geyBjaHJJZCwgc3RhcnQsIGVuZCB9XG4gICAgICBpZiAoIXRoaXMuY2lyVHJlZVByb21pc2UpIHtcbiAgICAgICAgdGhpcy5jaXJUcmVlUHJvbWlzZSA9IGJiaS5yZWFkKEJ1ZmZlci5hbGxvYyg0OCksIDAsIDQ4LCBjaXJUcmVlT2Zmc2V0LCB7IHNpZ25hbCB9KVxuICAgICAgfVxuICAgICAgY29uc3QgeyBidWZmZXIgfSA9IGF3YWl0IHRoaXMuY2lyVHJlZVByb21pc2VcbiAgICAgIGNvbnN0IGNpckJsb2NrU2l6ZSA9IGlzQmlnRW5kaWFuID8gYnVmZmVyLnJlYWRVSW50MzJCRSg0KSA6IGJ1ZmZlci5yZWFkVUludDMyTEUoNClcbiAgICAgIGxldCBibG9ja3NUb0ZldGNoOiBhbnlbXSA9IFtdXG4gICAgICBsZXQgb3V0c3RhbmRpbmcgPSAwXG5cbiAgICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdFxuICAgICAgbGV0IGNpckZvYlJlY3VyMjogRnVuY3Rpb25cblxuICAgICAgY29uc3QgZmlsdGVyRmVhdHMgPSAoYjogRGF0YUJsb2NrKTogYm9vbGVhbiA9PlxuICAgICAgICAoYi5zdGFydENocm9tIDwgY2hySWQgfHwgKGIuc3RhcnRDaHJvbSA9PT0gY2hySWQgJiYgYi5zdGFydEJhc2UgPD0gZW5kKSkgJiZcbiAgICAgICAgKGIuZW5kQ2hyb20gPiBjaHJJZCB8fCAoYi5lbmRDaHJvbSA9PT0gY2hySWQgJiYgYi5lbmRCYXNlID49IHN0YXJ0KSlcblxuICAgICAgY29uc3QgY2lyRm9iU3RhcnRGZXRjaCA9IGFzeW5jIChvZmY6IGFueSwgZnI6IGFueSwgbGV2ZWw6IG51bWJlcik6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IGZyLm1heCgpIC0gZnIubWluKClcbiAgICAgICAgICBjb25zdCBvZmZzZXQgPSBmci5taW4oKVxuICAgICAgICAgIGNvbnN0IHJlc3VsdEJ1ZmZlciA9IGF3YWl0IHRoaXMuZmVhdHVyZUNhY2hlLmdldChgJHtsZW5ndGh9XyR7b2Zmc2V0fWAsIHsgbGVuZ3RoLCBvZmZzZXQgfSwgc2lnbmFsKVxuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgb2ZmLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBpZiAoZnIuY29udGFpbnMob2ZmW2ldKSkge1xuICAgICAgICAgICAgICBjaXJGb2JSZWN1cjIocmVzdWx0QnVmZmVyLCBvZmZbaV0gLSBvZmZzZXQsIGxldmVsLCBvYnNlcnZlciwgb3B0cylcbiAgICAgICAgICAgICAgb3V0c3RhbmRpbmcgLT0gMVxuICAgICAgICAgICAgICBpZiAob3V0c3RhbmRpbmcgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlYWRGZWF0dXJlcyhvYnNlcnZlciwgYmxvY2tzVG9GZXRjaCwgeyAuLi5vcHRzLCByZXF1ZXN0IH0pXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBvYnNlcnZlci5lcnJvcihlKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBjaXJGb2JSZWN1ciA9IChvZmZzZXQ6IGFueSwgbGV2ZWw6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIG91dHN0YW5kaW5nICs9IG9mZnNldC5sZW5ndGhcblxuICAgICAgICAgIGNvbnN0IG1heENpckJsb2NrU3BhbiA9IDQgKyBjaXJCbG9ja1NpemUgKiAzMiAvLyBVcHBlciBib3VuZCBvbiBzaXplLCBiYXNlZCBvbiBhIGNvbXBsZXRlbHkgZnVsbCBsZWFmIG5vZGUuXG4gICAgICAgICAgbGV0IHNwYW5zID0gbmV3IFJhbmdlKG9mZnNldFswXSwgb2Zmc2V0WzBdICsgbWF4Q2lyQmxvY2tTcGFuKVxuICAgICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgb2Zmc2V0Lmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBjb25zdCBibG9ja1NwYW4gPSBuZXcgUmFuZ2Uob2Zmc2V0W2ldLCBvZmZzZXRbaV0gKyBtYXhDaXJCbG9ja1NwYW4pXG4gICAgICAgICAgICBzcGFucyA9IHNwYW5zLnVuaW9uKGJsb2NrU3BhbilcbiAgICAgICAgICB9XG4gICAgICAgICAgc3BhbnMuZ2V0UmFuZ2VzKCkubWFwKChmcjogUmFuZ2UpID0+IGNpckZvYlN0YXJ0RmV0Y2gob2Zmc2V0LCBmciwgbGV2ZWwpKVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZSlcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjaXJGb2JSZWN1cjIgPSAoY2lyQmxvY2tEYXRhOiBCdWZmZXIsIG9mZnNldDogbnVtYmVyLCBsZXZlbDogbnVtYmVyKTogdm9pZCA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgZGF0YSA9IGNpckJsb2NrRGF0YS5zbGljZShvZmZzZXQpXG5cbiAgICAgICAgICBjb25zdCBwID0gdGhpcy5sZWFmUGFyc2VyLnBhcnNlKGRhdGEpLnJlc3VsdFxuICAgICAgICAgIGlmIChwLmJsb2Nrc1RvRmV0Y2gpIHtcbiAgICAgICAgICAgIGJsb2Nrc1RvRmV0Y2ggPSBibG9ja3NUb0ZldGNoLmNvbmNhdChcbiAgICAgICAgICAgICAgcC5ibG9ja3NUb0ZldGNoXG4gICAgICAgICAgICAgICAgLmZpbHRlcihmaWx0ZXJGZWF0cylcbiAgICAgICAgICAgICAgICAubWFwKChsOiBhbnkpOiBhbnkgPT4gKHsgb2Zmc2V0OiBsLmJsb2NrT2Zmc2V0LCBsZW5ndGg6IGwuYmxvY2tTaXplIH0pKSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHAucmVjdXJPZmZzZXRzKSB7XG4gICAgICAgICAgICBjb25zdCByZWN1ck9mZnNldHMgPSBwLnJlY3VyT2Zmc2V0cy5maWx0ZXIoZmlsdGVyRmVhdHMpLm1hcCgobDogYW55KTogYW55ID0+IGwuYmxvY2tPZmZzZXQpXG4gICAgICAgICAgICBpZiAocmVjdXJPZmZzZXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgY2lyRm9iUmVjdXIocmVjdXJPZmZzZXRzLCBsZXZlbCArIDEpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgb2JzZXJ2ZXIuZXJyb3IoZSlcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2lyRm9iUmVjdXIoW2NpclRyZWVPZmZzZXQgKyA0OF0sIDEpXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgb2JzZXJ2ZXIuZXJyb3IoZSlcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBhcnNlU3VtbWFyeUJsb2NrKGRhdGE6IEJ1ZmZlciwgc3RhcnRPZmZzZXQ6IG51bWJlciwgcmVxdWVzdD86IENvb3JkUmVxdWVzdCk6IEZlYXR1cmVbXSB7XG4gICAgY29uc3QgZmVhdHVyZXMgPSBbXVxuICAgIGxldCBjdXJyT2Zmc2V0ID0gc3RhcnRPZmZzZXRcbiAgICB3aGlsZSAoY3Vyck9mZnNldCA8IGRhdGEuYnl0ZUxlbmd0aCkge1xuICAgICAgY29uc3QgcmVzID0gdGhpcy5zdW1tYXJ5UGFyc2VyLnBhcnNlKGRhdGEuc2xpY2UoY3Vyck9mZnNldCkpXG4gICAgICBmZWF0dXJlcy5wdXNoKHJlcy5yZXN1bHQpXG4gICAgICBjdXJyT2Zmc2V0ICs9IHJlcy5vZmZzZXRcbiAgICB9XG4gICAgbGV0IGl0ZW1zID0gZmVhdHVyZXNcbiAgICBpZiAocmVxdWVzdCkgaXRlbXMgPSBpdGVtcy5maWx0ZXIoKGVsdDogU3VtbWFyeUJsb2NrKTogYm9vbGVhbiA9PiBlbHQuY2hyb21JZCA9PT0gcmVxdWVzdC5jaHJJZClcbiAgICBpdGVtcyA9IGl0ZW1zLm1hcChcbiAgICAgIChlbHQ6IFN1bW1hcnlCbG9jayk6IEZlYXR1cmUgPT4gKHtcbiAgICAgICAgc3RhcnQ6IGVsdC5zdGFydCxcbiAgICAgICAgZW5kOiBlbHQuZW5kLFxuICAgICAgICBtYXhTY29yZTogZWx0Lm1heFNjb3JlLFxuICAgICAgICBtaW5TY29yZTogZWx0Lm1pblNjb3JlLFxuICAgICAgICBzY29yZTogZWx0LnN1bURhdGEgLyAoZWx0LnZhbGlkQ250IHx8IDEpLFxuICAgICAgICBzdW1tYXJ5OiB0cnVlLFxuICAgICAgfSksXG4gICAgKVxuICAgIHJldHVybiByZXF1ZXN0ID8gaXRlbXMuZmlsdGVyKGYgPT4gQmxvY2tWaWV3LmNvb3JkRmlsdGVyKGYsIHJlcXVlc3QpKSA6IGl0ZW1zXG4gIH1cblxuICBwcml2YXRlIHBhcnNlQmlnQmVkQmxvY2soZGF0YTogQnVmZmVyLCBzdGFydE9mZnNldDogbnVtYmVyLCBvZmZzZXQ6IG51bWJlciwgcmVxdWVzdD86IENvb3JkUmVxdWVzdCk6IEZlYXR1cmVbXSB7XG4gICAgY29uc3QgaXRlbXMgPSBbXVxuICAgIGxldCBjdXJyT2Zmc2V0ID0gc3RhcnRPZmZzZXRcbiAgICB3aGlsZSAoY3Vyck9mZnNldCA8IGRhdGEuYnl0ZUxlbmd0aCkge1xuICAgICAgY29uc3QgcmVzID0gdGhpcy5iaWdCZWRQYXJzZXIucGFyc2UoZGF0YS5zbGljZShjdXJyT2Zmc2V0KSlcbiAgICAgIHJlcy5yZXN1bHQudW5pcXVlSWQgPSBgYmItJHtvZmZzZXQgKyBjdXJyT2Zmc2V0fWBcbiAgICAgIGl0ZW1zLnB1c2gocmVzLnJlc3VsdClcbiAgICAgIGN1cnJPZmZzZXQgKz0gcmVzLm9mZnNldFxuICAgIH1cblxuICAgIHJldHVybiByZXF1ZXN0ID8gaXRlbXMuZmlsdGVyKChmOiBhbnkpID0+IEJsb2NrVmlldy5jb29yZEZpbHRlcihmLCByZXF1ZXN0KSkgOiBpdGVtc1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUJpZ1dpZ0Jsb2NrKGJ5dGVzOiBCdWZmZXIsIHN0YXJ0T2Zmc2V0OiBudW1iZXIsIHJlcXVlc3Q/OiBDb29yZFJlcXVlc3QpOiBGZWF0dXJlW10ge1xuICAgIGNvbnN0IGRhdGEgPSBieXRlcy5zbGljZShzdGFydE9mZnNldClcbiAgICBjb25zdCByZXN1bHRzID0gdGhpcy5iaWdXaWdQYXJzZXIucGFyc2UoZGF0YSkucmVzdWx0XG4gICAgY29uc3QgeyBpdGVtcywgaXRlbVNwYW4sIGl0ZW1TdGVwLCBibG9ja1N0YXJ0LCBibG9ja1R5cGUgfSA9IHJlc3VsdHNcbiAgICBpZiAoYmxvY2tUeXBlID09PSBCSUdfV0lHX1RZUEVfRlNURVApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlbXNbaV0uc3RhcnQgPSBibG9ja1N0YXJ0ICsgaSAqIGl0ZW1TdGVwXG4gICAgICAgIGl0ZW1zW2ldLmVuZCA9IGJsb2NrU3RhcnQgKyBpICogaXRlbVN0ZXAgKyBpdGVtU3BhblxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYmxvY2tUeXBlID09PSBCSUdfV0lHX1RZUEVfVlNURVApIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaXRlbXNbaV0uZW5kID0gaXRlbXNbaV0uc3RhcnQgKyBpdGVtU3BhblxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVxdWVzdCA/IGl0ZW1zLmZpbHRlcigoZjogYW55KSA9PiBCbG9ja1ZpZXcuY29vcmRGaWx0ZXIoZiwgcmVxdWVzdCkpIDogaXRlbXNcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGNvb3JkRmlsdGVyKGY6IEZlYXR1cmUsIHJhbmdlOiBDb29yZFJlcXVlc3QpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZi5zdGFydCA8IHJhbmdlLmVuZCAmJiBmLmVuZCA+PSByYW5nZS5zdGFydFxuICB9XG5cbiAgcHVibGljIGFzeW5jIHJlYWRGZWF0dXJlcyhvYnNlcnZlcjogT2JzZXJ2ZXI8RmVhdHVyZVtdPiwgYmxvY2tzOiBhbnksIG9wdHM6IE9wdGlvbnMgPSB7fSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB7IGJsb2NrVHlwZSwgaXNDb21wcmVzc2VkIH0gPSB0aGlzXG4gICAgICBjb25zdCB7IHNpZ25hbCwgcmVxdWVzdCB9ID0gb3B0c1xuICAgICAgY29uc3QgYmxvY2tHcm91cHNUb0ZldGNoID0gZ3JvdXBCbG9ja3MoYmxvY2tzKVxuICAgICAgY2hlY2tBYm9ydFNpZ25hbChzaWduYWwpXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgYmxvY2tHcm91cHNUb0ZldGNoLm1hcChhc3luYyAoYmxvY2tHcm91cDogYW55KSA9PiB7XG4gICAgICAgICAgY2hlY2tBYm9ydFNpZ25hbChzaWduYWwpXG4gICAgICAgICAgY29uc3QgeyBsZW5ndGgsIG9mZnNldCB9ID0gYmxvY2tHcm91cFxuICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0aGlzLmZlYXR1cmVDYWNoZS5nZXQoYCR7bGVuZ3RofV8ke29mZnNldH1gLCBibG9ja0dyb3VwLCBzaWduYWwpXG4gICAgICAgICAgYmxvY2tHcm91cC5ibG9ja3MuZm9yRWFjaCgoYmxvY2s6IGFueSkgPT4ge1xuICAgICAgICAgICAgY2hlY2tBYm9ydFNpZ25hbChzaWduYWwpXG4gICAgICAgICAgICBsZXQgYmxvY2tPZmZzZXQgPSBibG9jay5vZmZzZXQgLSBibG9ja0dyb3VwLm9mZnNldFxuICAgICAgICAgICAgbGV0IHJlc3VsdERhdGEgPSBkYXRhXG4gICAgICAgICAgICBpZiAoaXNDb21wcmVzc2VkKSB7XG4gICAgICAgICAgICAgIHJlc3VsdERhdGEgPSB6bGliLmluZmxhdGVTeW5jKGRhdGEuc2xpY2UoYmxvY2tPZmZzZXQpKVxuICAgICAgICAgICAgICBibG9ja09mZnNldCA9IDBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNoZWNrQWJvcnRTaWduYWwoc2lnbmFsKVxuXG4gICAgICAgICAgICBzd2l0Y2ggKGJsb2NrVHlwZSkge1xuICAgICAgICAgICAgICBjYXNlICdzdW1tYXJ5JzpcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHRoaXMucGFyc2VTdW1tYXJ5QmxvY2socmVzdWx0RGF0YSwgYmxvY2tPZmZzZXQsIHJlcXVlc3QpKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIGNhc2UgJ2JpZ3dpZyc6XG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh0aGlzLnBhcnNlQmlnV2lnQmxvY2socmVzdWx0RGF0YSwgYmxvY2tPZmZzZXQsIHJlcXVlc3QpKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIGNhc2UgJ2JpZ2JlZCc6XG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2VcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KHRoaXMucGFyc2VCaWdCZWRCbG9jayhyZXN1bHREYXRhLCBibG9ja09mZnNldCwgYmxvY2sub2Zmc2V0ICogKDEgPDwgOCksIHJlcXVlc3QpKVxuICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCAke2Jsb2NrVHlwZX1gKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pXG4gICAgICAgIH0pLFxuICAgICAgKVxuICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIG9ic2VydmVyLmVycm9yKGUpXG4gICAgfVxuICB9XG59XG4iXX0=