@gmod/tabix 1.4.4 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tbi.js CHANGED
@@ -1,533 +1,326 @@
1
1
  "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime-corejs2/helpers/interopRequireWildcard");
4
-
5
- var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
6
-
7
- var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
8
-
9
- _Object$defineProperty(exports, "__esModule", {
10
- value: true
2
+ var __extends = (this && this.__extends) || (function () {
3
+ var extendStatics = function (d, b) {
4
+ extendStatics = Object.setPrototypeOf ||
5
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
7
+ return extendStatics(d, b);
8
+ };
9
+ return function (d, b) {
10
+ if (typeof b !== "function" && b !== null)
11
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
12
+ extendStatics(d, b);
13
+ function __() { this.constructor = d; }
14
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
15
+ };
16
+ })();
17
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
20
+ }) : (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ o[k2] = m[k];
23
+ }));
24
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
25
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
26
+ }) : function(o, v) {
27
+ o["default"] = v;
11
28
  });
12
-
13
- exports.default = void 0;
14
-
15
- var _construct = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/construct"));
16
-
17
- var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
18
-
19
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
20
-
21
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
22
-
23
- var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
24
-
25
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
26
-
27
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
28
-
29
- var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
30
-
31
- var _long = _interopRequireDefault(require("long"));
32
-
33
- var _virtualOffset = _interopRequireWildcard(require("./virtualOffset"));
34
-
35
- var _chunk = _interopRequireDefault(require("./chunk"));
36
-
37
- var _bgzfFilehandle = require("@gmod/bgzf-filehandle");
38
-
39
- var _util = require("./util");
40
-
41
- var _indexFile = _interopRequireDefault(require("./indexFile"));
42
-
43
- function _createSuper(Derived) { return function () { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = (0, _construct.default)(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
44
-
45
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_construct.default) return false; if (_construct.default.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call((0, _construct.default)(Date, [], function () {})); return true; } catch (e) { return false; } }
46
-
29
+ var __importStar = (this && this.__importStar) || function (mod) {
30
+ if (mod && mod.__esModule) return mod;
31
+ var result = {};
32
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
33
+ __setModuleDefault(result, mod);
34
+ return result;
35
+ };
36
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
37
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
38
+ return new (P || (P = Promise))(function (resolve, reject) {
39
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
40
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
41
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
42
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
43
+ });
44
+ };
45
+ var __generator = (this && this.__generator) || function (thisArg, body) {
46
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
47
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
48
+ function verb(n) { return function (v) { return step([n, v]); }; }
49
+ function step(op) {
50
+ if (f) throw new TypeError("Generator is already executing.");
51
+ while (_) try {
52
+ 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;
53
+ if (y = 0, t) op = [op[0] & 2, t.value];
54
+ switch (op[0]) {
55
+ case 0: case 1: t = op; break;
56
+ case 4: _.label++; return { value: op[1], done: false };
57
+ case 5: _.label++; y = op[1]; op = [0]; continue;
58
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
59
+ default:
60
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
61
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
62
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
63
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
64
+ if (t[2]) _.ops.pop();
65
+ _.trys.pop(); continue;
66
+ }
67
+ op = body.call(thisArg, _);
68
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
69
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
70
+ }
71
+ };
72
+ var __importDefault = (this && this.__importDefault) || function (mod) {
73
+ return (mod && mod.__esModule) ? mod : { "default": mod };
74
+ };
75
+ Object.defineProperty(exports, "__esModule", { value: true });
76
+ var long_1 = __importDefault(require("long"));
77
+ var virtualOffset_1 = __importStar(require("./virtualOffset"));
78
+ var chunk_1 = __importDefault(require("./chunk"));
79
+ var bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
80
+ var util_1 = require("./util");
81
+ var indexFile_1 = __importDefault(require("./indexFile"));
47
82
  var TBI_MAGIC = 21578324; // TBI\1
48
-
49
83
  var TAD_LIDX_SHIFT = 14;
50
84
  /**
51
85
  * calculate the list of bins that may overlap with region [beg,end) (zero-based half-open)
52
- * @returns {Array[number]}
53
86
  */
54
-
55
87
  function reg2bins(beg, end) {
56
- beg += 1; // < convert to 1-based closed
57
-
58
- end -= 1;
59
- var list = [0];
60
-
61
- for (var k = 1 + (beg >> 26); k <= 1 + (end >> 26); k += 1) {
62
- list.push(k);
63
- }
64
-
65
- for (var _k = 9 + (beg >> 23); _k <= 9 + (end >> 23); _k += 1) {
66
- list.push(_k);
67
- }
68
-
69
- for (var _k2 = 73 + (beg >> 20); _k2 <= 73 + (end >> 20); _k2 += 1) {
70
- list.push(_k2);
71
- }
72
-
73
- for (var _k3 = 585 + (beg >> 17); _k3 <= 585 + (end >> 17); _k3 += 1) {
74
- list.push(_k3);
75
- }
76
-
77
- for (var _k4 = 4681 + (beg >> 14); _k4 <= 4681 + (end >> 14); _k4 += 1) {
78
- list.push(_k4);
79
- }
80
-
81
- return list;
88
+ beg += 1; // < convert to 1-based closed
89
+ end -= 1;
90
+ return [
91
+ [0, 0],
92
+ [1 + (beg >> 26), 1 + (end >> 26)],
93
+ [9 + (beg >> 23), 9 + (end >> 23)],
94
+ [73 + (beg >> 20), 73 + (end >> 20)],
95
+ [585 + (beg >> 17), 585 + (end >> 17)],
96
+ [4681 + (beg >> 14), 4681 + (end >> 14)],
97
+ ];
82
98
  }
83
-
84
- var TabixIndex = /*#__PURE__*/function (_IndexFile) {
85
- (0, _inherits2.default)(TabixIndex, _IndexFile);
86
-
87
- var _super = _createSuper(TabixIndex);
88
-
89
- function TabixIndex() {
90
- (0, _classCallCheck2.default)(this, TabixIndex);
91
- return _super.apply(this, arguments);
92
- }
93
-
94
- (0, _createClass2.default)(TabixIndex, [{
95
- key: "lineCount",
96
- value: function () {
97
- var _lineCount = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(refName) {
98
- var opts,
99
- indexData,
100
- refId,
101
- idx,
102
- stats,
103
- _args = arguments;
104
- return _regenerator.default.wrap(function _callee$(_context) {
105
- while (1) {
106
- switch (_context.prev = _context.next) {
107
- case 0:
108
- opts = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
109
- _context.next = 3;
110
- return this.parse(opts);
111
-
112
- case 3:
113
- indexData = _context.sent;
114
-
115
- if (indexData) {
116
- _context.next = 6;
117
- break;
118
- }
119
-
120
- return _context.abrupt("return", -1);
121
-
122
- case 6:
123
- refId = indexData.refNameToId[refName];
124
- idx = indexData.indices[refId];
125
-
126
- if (idx) {
127
- _context.next = 10;
128
- break;
129
- }
130
-
131
- return _context.abrupt("return", -1);
132
-
133
- case 10:
134
- stats = indexData.indices[refId].stats;
135
-
136
- if (!stats) {
137
- _context.next = 13;
138
- break;
99
+ var TabixIndex = /** @class */ (function (_super) {
100
+ __extends(TabixIndex, _super);
101
+ function TabixIndex() {
102
+ return _super !== null && _super.apply(this, arguments) || this;
103
+ }
104
+ TabixIndex.prototype.lineCount = function (refName, opts) {
105
+ if (opts === void 0) { opts = {}; }
106
+ return __awaiter(this, void 0, void 0, function () {
107
+ var indexData, refId, idx, stats;
108
+ return __generator(this, function (_a) {
109
+ switch (_a.label) {
110
+ case 0: return [4 /*yield*/, this.parse(opts)];
111
+ case 1:
112
+ indexData = _a.sent();
113
+ if (!indexData) {
114
+ return [2 /*return*/, -1];
115
+ }
116
+ refId = indexData.refNameToId[refName];
117
+ idx = indexData.indices[refId];
118
+ if (!idx) {
119
+ return [2 /*return*/, -1];
120
+ }
121
+ stats = indexData.indices[refId].stats;
122
+ if (stats) {
123
+ return [2 /*return*/, stats.lineCount];
124
+ }
125
+ return [2 /*return*/, -1];
139
126
  }
140
-
141
- return _context.abrupt("return", stats.lineCount);
142
-
143
- case 13:
144
- return _context.abrupt("return", -1);
145
-
146
- case 14:
147
- case "end":
148
- return _context.stop();
149
- }
150
- }
151
- }, _callee, this);
152
- }));
153
-
154
- function lineCount(_x) {
155
- return _lineCount.apply(this, arguments);
156
- }
157
-
158
- return lineCount;
159
- }() // memoize
127
+ });
128
+ });
129
+ };
130
+ // memoize
160
131
  // fetch and parse the index
161
-
162
- }, {
163
- key: "_parse",
164
- value: function () {
165
- var _parse2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
166
- var _this = this;
167
-
168
- var opts,
169
- bytes,
170
- refCount,
171
- formatFlags,
172
- coordinateType,
173
- formatOpts,
174
- format,
175
- columnNumbers,
176
- metaValue,
177
- depth,
178
- maxBinNumber,
179
- maxRefLength,
180
- metaChar,
181
- skipLines,
182
- nameSectionLength,
183
- _this$_parseNameBytes,
184
- refNameToId,
185
- refIdToName,
186
- currOffset,
187
- firstDataLine,
188
- indices,
189
- _args2 = arguments;
190
-
191
- return _regenerator.default.wrap(function _callee2$(_context2) {
192
- while (1) {
193
- switch (_context2.prev = _context2.next) {
194
- case 0:
195
- opts = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};
196
- _context2.t0 = _bgzfFilehandle.unzip;
197
- _context2.next = 4;
198
- return this.filehandle.readFile(opts);
199
-
200
- case 4:
201
- _context2.t1 = _context2.sent;
202
- _context2.next = 7;
203
- return (0, _context2.t0)(_context2.t1);
204
-
205
- case 7:
206
- bytes = _context2.sent;
207
- (0, _util.checkAbortSignal)(opts.signal); // check TBI magic numbers
208
-
209
- if (!(bytes.readUInt32LE(0) !== TBI_MAGIC
210
- /* "TBI\1" */
211
- )) {
212
- _context2.next = 11;
213
- break;
132
+ TabixIndex.prototype._parse = function (opts) {
133
+ if (opts === void 0) { opts = {}; }
134
+ return __awaiter(this, void 0, void 0, function () {
135
+ var bytes, _a, refCount, formatFlags, coordinateType, formatOpts, format, columnNumbers, metaValue, depth, maxBinNumber, maxRefLength, metaChar, skipLines, nameSectionLength, _b, refNameToId, refIdToName, currOffset, firstDataLine, indices;
136
+ var _this = this;
137
+ return __generator(this, function (_c) {
138
+ switch (_c.label) {
139
+ case 0:
140
+ _a = bgzf_filehandle_1.unzip;
141
+ return [4 /*yield*/, this.filehandle.readFile(opts)];
142
+ case 1: return [4 /*yield*/, _a.apply(void 0, [(_c.sent())])];
143
+ case 2:
144
+ bytes = _c.sent();
145
+ (0, util_1.checkAbortSignal)(opts.signal);
146
+ // check TBI magic numbers
147
+ if (bytes.readUInt32LE(0) !== TBI_MAGIC /* "TBI\1" */) {
148
+ throw new Error('Not a TBI file');
149
+ // TODO: do we need to support big-endian TBI files?
150
+ }
151
+ refCount = bytes.readInt32LE(4);
152
+ formatFlags = bytes.readInt32LE(8);
153
+ coordinateType = formatFlags & 0x10000 ? 'zero-based-half-open' : '1-based-closed';
154
+ formatOpts = {
155
+ 0: 'generic',
156
+ 1: 'SAM',
157
+ 2: 'VCF',
158
+ };
159
+ format = formatOpts[formatFlags & 0xf];
160
+ if (!format) {
161
+ throw new Error("invalid Tabix preset format flags ".concat(formatFlags));
162
+ }
163
+ columnNumbers = {
164
+ ref: bytes.readInt32LE(12),
165
+ start: bytes.readInt32LE(16),
166
+ end: bytes.readInt32LE(20),
167
+ };
168
+ metaValue = bytes.readInt32LE(24);
169
+ depth = 5;
170
+ maxBinNumber = ((1 << ((depth + 1) * 3)) - 1) / 7;
171
+ maxRefLength = Math.pow(2, (14 + depth * 3));
172
+ metaChar = metaValue ? String.fromCharCode(metaValue) : null;
173
+ skipLines = bytes.readInt32LE(28);
174
+ nameSectionLength = bytes.readInt32LE(32);
175
+ _b = this._parseNameBytes(bytes.slice(36, 36 + nameSectionLength)), refNameToId = _b.refNameToId, refIdToName = _b.refIdToName;
176
+ currOffset = 36 + nameSectionLength;
177
+ indices = new Array(refCount).fill(0).map(function () {
178
+ // the binning index
179
+ var binCount = bytes.readInt32LE(currOffset);
180
+ currOffset += 4;
181
+ var binIndex = {};
182
+ var stats;
183
+ for (var j = 0; j < binCount; j += 1) {
184
+ var bin = bytes.readUInt32LE(currOffset);
185
+ currOffset += 4;
186
+ if (bin > maxBinNumber + 1) {
187
+ throw new Error('tabix index contains too many bins, please use a CSI index');
188
+ }
189
+ else if (bin === maxBinNumber + 1) {
190
+ var chunkCount = bytes.readInt32LE(currOffset);
191
+ currOffset += 4;
192
+ if (chunkCount === 2) {
193
+ stats = _this.parsePseudoBin(bytes, currOffset);
194
+ }
195
+ currOffset += 16 * chunkCount;
196
+ }
197
+ else {
198
+ var chunkCount = bytes.readInt32LE(currOffset);
199
+ currOffset += 4;
200
+ var chunks = new Array(chunkCount);
201
+ for (var k = 0; k < chunkCount; k += 1) {
202
+ var u = (0, virtualOffset_1.fromBytes)(bytes, currOffset);
203
+ var v = (0, virtualOffset_1.fromBytes)(bytes, currOffset + 8);
204
+ currOffset += 16;
205
+ firstDataLine = _this._findFirstData(firstDataLine, u);
206
+ chunks[k] = new chunk_1.default(u, v, bin);
207
+ }
208
+ binIndex[bin] = chunks;
209
+ }
210
+ }
211
+ // the linear index
212
+ var linearCount = bytes.readInt32LE(currOffset);
213
+ currOffset += 4;
214
+ var linearIndex = new Array(linearCount);
215
+ for (var k = 0; k < linearCount; k += 1) {
216
+ linearIndex[k] = (0, virtualOffset_1.fromBytes)(bytes, currOffset);
217
+ currOffset += 8;
218
+ firstDataLine = _this._findFirstData(firstDataLine, linearIndex[k]);
219
+ }
220
+ return { binIndex: binIndex, linearIndex: linearIndex, stats: stats };
221
+ });
222
+ return [2 /*return*/, {
223
+ indices: indices,
224
+ metaChar: metaChar,
225
+ maxBinNumber: maxBinNumber,
226
+ maxRefLength: maxRefLength,
227
+ skipLines: skipLines,
228
+ firstDataLine: firstDataLine,
229
+ columnNumbers: columnNumbers,
230
+ coordinateType: coordinateType,
231
+ format: format,
232
+ refIdToName: refIdToName,
233
+ refNameToId: refNameToId,
234
+ maxBlockSize: 1 << 16,
235
+ }];
214
236
  }
215
-
216
- throw new Error('Not a TBI file');
217
-
218
- case 11:
219
- // number of reference sequences in the index
220
- refCount = bytes.readInt32LE(4);
221
- formatFlags = bytes.readInt32LE(8);
222
- coordinateType = formatFlags & 0x10000 ? 'zero-based-half-open' : '1-based-closed';
223
- formatOpts = {
224
- 0: 'generic',
225
- 1: 'SAM',
226
- 2: 'VCF'
227
- };
228
- format = formatOpts[formatFlags & 0xf];
229
-
230
- if (format) {
231
- _context2.next = 18;
232
- break;
237
+ });
238
+ });
239
+ };
240
+ TabixIndex.prototype.parsePseudoBin = function (bytes, offset) {
241
+ var lineCount = (0, util_1.longToNumber)(long_1.default.fromBytesLE(bytes.slice(offset + 16, offset + 24), true));
242
+ return { lineCount: lineCount };
243
+ };
244
+ TabixIndex.prototype._parseNameBytes = function (namesBytes) {
245
+ var currRefId = 0;
246
+ var currNameStart = 0;
247
+ var refIdToName = [];
248
+ var refNameToId = {};
249
+ for (var i = 0; i < namesBytes.length; i += 1) {
250
+ if (!namesBytes[i]) {
251
+ if (currNameStart < i) {
252
+ var refName = namesBytes.toString('utf8', currNameStart, i);
253
+ refName = this.renameRefSeq(refName);
254
+ refIdToName[currRefId] = refName;
255
+ refNameToId[refName] = currRefId;
233
256
  }
234
-
235
- throw new Error("invalid Tabix preset format flags ".concat(formatFlags));
236
-
237
- case 18:
238
- columnNumbers = {
239
- ref: bytes.readInt32LE(12),
240
- start: bytes.readInt32LE(16),
241
- end: bytes.readInt32LE(20)
242
- };
243
- metaValue = bytes.readInt32LE(24);
244
- depth = 5;
245
- maxBinNumber = ((1 << (depth + 1) * 3) - 1) / 7;
246
- maxRefLength = Math.pow(2, 14 + depth * 3);
247
- metaChar = metaValue ? String.fromCharCode(metaValue) : null;
248
- skipLines = bytes.readInt32LE(28); // read sequence dictionary
249
-
250
- nameSectionLength = bytes.readInt32LE(32);
251
- _this$_parseNameBytes = this._parseNameBytes(bytes.slice(36, 36 + nameSectionLength)), refNameToId = _this$_parseNameBytes.refNameToId, refIdToName = _this$_parseNameBytes.refIdToName; // read the indexes for each reference sequence
252
-
253
- currOffset = 36 + nameSectionLength;
254
- indices = new Array(refCount).fill(0).map(function () {
255
- // the binning index
256
- var binCount = bytes.readInt32LE(currOffset);
257
- currOffset += 4;
258
- var binIndex = {};
259
- var stats;
260
-
261
- for (var j = 0; j < binCount; j += 1) {
262
- var bin = bytes.readUInt32LE(currOffset);
263
- currOffset += 4;
264
-
265
- if (bin > maxBinNumber + 1) {
266
- throw new Error('tabix index contains too many bins, please use a CSI index');
267
- } else if (bin === maxBinNumber + 1) {
268
- var chunkCount = bytes.readInt32LE(currOffset);
269
- currOffset += 4;
270
-
271
- if (chunkCount === 2) {
272
- stats = _this.parsePseudoBin(bytes, currOffset);
273
- }
274
-
275
- currOffset += 16 * chunkCount;
276
- } else {
277
- var _chunkCount = bytes.readInt32LE(currOffset);
278
-
279
- currOffset += 4;
280
- var chunks = new Array(_chunkCount);
281
-
282
- for (var k = 0; k < _chunkCount; k += 1) {
283
- var u = (0, _virtualOffset.fromBytes)(bytes, currOffset);
284
- var v = (0, _virtualOffset.fromBytes)(bytes, currOffset + 8);
285
- currOffset += 16;
286
- firstDataLine = _this._findFirstData(firstDataLine, u);
287
- chunks[k] = new _chunk.default(u, v, bin);
288
- }
289
-
290
- binIndex[bin] = chunks;
291
- }
292
- } // the linear index
293
-
294
-
295
- var linearCount = bytes.readInt32LE(currOffset);
296
- currOffset += 4;
297
- var linearIndex = new Array(linearCount);
298
-
299
- for (var _k5 = 0; _k5 < linearCount; _k5 += 1) {
300
- linearIndex[_k5] = (0, _virtualOffset.fromBytes)(bytes, currOffset);
301
- currOffset += 8;
302
- firstDataLine = _this._findFirstData(firstDataLine, linearIndex[_k5]);
303
- }
304
-
305
- return {
306
- binIndex: binIndex,
307
- linearIndex: linearIndex,
308
- stats: stats
309
- };
310
- });
311
- return _context2.abrupt("return", {
312
- indices: indices,
313
- metaChar: metaChar,
314
- maxBinNumber: maxBinNumber,
315
- maxRefLength: maxRefLength,
316
- skipLines: skipLines,
317
- firstDataLine: firstDataLine,
318
- columnNumbers: columnNumbers,
319
- coordinateType: coordinateType,
320
- format: format,
321
- refIdToName: refIdToName,
322
- refNameToId: refNameToId,
323
- maxBlockSize: 1 << 16
324
- });
325
-
326
- case 30:
327
- case "end":
328
- return _context2.stop();
257
+ currNameStart = i + 1;
258
+ currRefId += 1;
329
259
  }
330
- }
331
- }, _callee2, this);
332
- }));
333
-
334
- function _parse() {
335
- return _parse2.apply(this, arguments);
336
- }
337
-
338
- return _parse;
339
- }()
340
- }, {
341
- key: "parsePseudoBin",
342
- value: function parsePseudoBin(bytes, offset) {
343
- var lineCount = (0, _util.longToNumber)(_long.default.fromBytesLE(bytes.slice(offset + 16, offset + 24), true));
344
- return {
345
- lineCount: lineCount
346
- };
347
- }
348
- }, {
349
- key: "_parseNameBytes",
350
- value: function _parseNameBytes(namesBytes) {
351
- var currRefId = 0;
352
- var currNameStart = 0;
353
- var refIdToName = [];
354
- var refNameToId = {};
355
-
356
- for (var i = 0; i < namesBytes.length; i += 1) {
357
- if (!namesBytes[i]) {
358
- if (currNameStart < i) {
359
- var refName = namesBytes.toString('utf8', currNameStart, i);
360
- refName = this.renameRefSeq(refName);
361
- refIdToName[currRefId] = refName;
362
- refNameToId[refName] = currRefId;
363
- }
364
-
365
- currNameStart = i + 1;
366
- currRefId += 1;
367
260
  }
368
- }
369
-
370
- return {
371
- refNameToId: refNameToId,
372
- refIdToName: refIdToName
373
- };
374
- }
375
- }, {
376
- key: "blocksForRange",
377
- value: function () {
378
- var _blocksForRange = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(refName, beg, end) {
379
- var opts,
380
- indexData,
381
- refId,
382
- indexes,
383
- linearIndex,
384
- binIndex,
385
- bins,
386
- minOffset,
387
- l,
388
- numOffsets,
389
- i,
390
- off,
391
- _i,
392
- chunks,
393
- j,
394
- _i2,
395
- _i3,
396
- _i4,
397
- _args3 = arguments;
398
-
399
- return _regenerator.default.wrap(function _callee3$(_context3) {
400
- while (1) {
401
- switch (_context3.prev = _context3.next) {
402
- case 0:
403
- opts = _args3.length > 3 && _args3[3] !== undefined ? _args3[3] : {};
404
- if (beg < 0) beg = 0;
405
- _context3.next = 4;
406
- return this.parse(opts);
407
-
408
- case 4:
409
- indexData = _context3.sent;
410
-
411
- if (indexData) {
412
- _context3.next = 7;
413
- break;
414
- }
415
-
416
- return _context3.abrupt("return", []);
417
-
418
- case 7:
419
- refId = indexData.refNameToId[refName];
420
- indexes = indexData.indices[refId];
421
-
422
- if (indexes) {
423
- _context3.next = 11;
424
- break;
261
+ return { refNameToId: refNameToId, refIdToName: refIdToName };
262
+ };
263
+ TabixIndex.prototype.blocksForRange = function (refName, min, max, opts) {
264
+ if (opts === void 0) { opts = {}; }
265
+ return __awaiter(this, void 0, void 0, function () {
266
+ var indexData, refId, ba, minOffset, overlappingBins, chunks, _i, overlappingBins_1, _a, start, end, bin, binChunks, c, nintv, lowest, minLin, maxLin, i, vp;
267
+ return __generator(this, function (_b) {
268
+ switch (_b.label) {
269
+ case 0:
270
+ if (min < 0) {
271
+ min = 0;
272
+ }
273
+ return [4 /*yield*/, this.parse(opts)];
274
+ case 1:
275
+ indexData = _b.sent();
276
+ if (!indexData) {
277
+ return [2 /*return*/, []];
278
+ }
279
+ refId = indexData.refNameToId[refName];
280
+ ba = indexData.indices[refId];
281
+ if (!ba) {
282
+ return [2 /*return*/, []];
283
+ }
284
+ minOffset = ba.linearIndex.length
285
+ ? ba.linearIndex[min >> TAD_LIDX_SHIFT >= ba.linearIndex.length
286
+ ? ba.linearIndex.length - 1
287
+ : min >> TAD_LIDX_SHIFT]
288
+ : new virtualOffset_1.default(0, 0);
289
+ if (!minOffset) {
290
+ console.warn('querying outside of possible tabix range');
291
+ }
292
+ overlappingBins = reg2bins(min, max) // List of bin #s that overlap min, max
293
+ ;
294
+ chunks = [];
295
+ // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned
296
+ for (_i = 0, overlappingBins_1 = overlappingBins; _i < overlappingBins_1.length; _i++) {
297
+ _a = overlappingBins_1[_i], start = _a[0], end = _a[1];
298
+ for (bin = start; bin <= end; bin++) {
299
+ if (ba.binIndex[bin]) {
300
+ binChunks = ba.binIndex[bin];
301
+ for (c = 0; c < binChunks.length; ++c) {
302
+ chunks.push(new chunk_1.default(binChunks[c].minv, binChunks[c].maxv, bin));
303
+ }
304
+ }
305
+ }
306
+ }
307
+ nintv = ba.linearIndex.length;
308
+ lowest = null;
309
+ minLin = Math.min(min >> 14, nintv - 1);
310
+ maxLin = Math.min(max >> 14, nintv - 1);
311
+ for (i = minLin; i <= maxLin; ++i) {
312
+ vp = ba.linearIndex[i];
313
+ if (vp) {
314
+ if (!lowest || vp.compareTo(lowest) < 0) {
315
+ lowest = vp;
316
+ }
317
+ }
318
+ }
319
+ return [2 /*return*/, (0, util_1.optimizeChunks)(chunks, lowest)];
425
320
  }
426
-
427
- return _context3.abrupt("return", []);
428
-
429
- case 11:
430
- linearIndex = indexes.linearIndex, binIndex = indexes.binIndex;
431
- bins = reg2bins(beg, end);
432
- minOffset = linearIndex.length ? linearIndex[beg >> TAD_LIDX_SHIFT >= linearIndex.length ? linearIndex.length - 1 : beg >> TAD_LIDX_SHIFT] : new _virtualOffset.default(0, 0);
433
-
434
- if (minOffset) {
435
- _context3.next = 17;
436
- break;
437
- }
438
-
439
- console.warn('querying outside of possible tabix range');
440
- return _context3.abrupt("return", []);
441
-
442
- case 17:
443
- numOffsets = 0;
444
-
445
- for (i = 0; i < bins.length; i += 1) {
446
- if (binIndex[bins[i]]) numOffsets += binIndex[bins[i]].length;
447
- }
448
-
449
- if (!(numOffsets === 0)) {
450
- _context3.next = 21;
451
- break;
452
- }
453
-
454
- return _context3.abrupt("return", []);
455
-
456
- case 21:
457
- off = [];
458
- numOffsets = 0;
459
-
460
- for (_i = 0; _i < bins.length; _i += 1) {
461
- chunks = binIndex[bins[_i]];
462
- if (chunks) for (j = 0; j < chunks.length; j += 1) {
463
- if (minOffset.compareTo(chunks[j].maxv) < 0) {
464
- off[numOffsets] = new _chunk.default(chunks[j].minv, chunks[j].maxv, chunks[j].bin);
465
- numOffsets += 1;
466
- }
467
- }
468
- }
469
-
470
- if (off.length) {
471
- _context3.next = 26;
472
- break;
473
- }
474
-
475
- return _context3.abrupt("return", []);
476
-
477
- case 26:
478
- off = off.sort(function (a, b) {
479
- return a.compareTo(b);
480
- }); // resolve completely contained adjacent blocks
481
-
482
- l = 0;
483
-
484
- for (_i2 = 1; _i2 < numOffsets; _i2 += 1) {
485
- if (off[l].maxv.compareTo(off[_i2].maxv) < 0) {
486
- l += 1;
487
- off[l].minv = off[_i2].minv;
488
- off[l].maxv = off[_i2].maxv;
489
- }
490
- }
491
-
492
- numOffsets = l + 1; // resolve overlaps between adjacent blocks; this may happen due to the merge in indexing
493
-
494
- for (_i3 = 1; _i3 < numOffsets; _i3 += 1) {
495
- if (off[_i3 - 1].maxv.compareTo(off[_i3].minv) >= 0) {
496
- off[_i3 - 1].maxv = off[_i3].minv;
497
- }
498
- } // merge adjacent blocks
499
-
500
-
501
- l = 0;
502
-
503
- for (_i4 = 1; _i4 < numOffsets; _i4 += 1) {
504
- if (off[l].maxv.blockPosition === off[_i4].minv.blockPosition) off[l].maxv = off[_i4].maxv;else {
505
- l += 1;
506
- off[l].minv = off[_i4].minv;
507
- off[l].maxv = off[_i4].maxv;
508
- }
509
- }
510
-
511
- numOffsets = l + 1;
512
- return _context3.abrupt("return", off.slice(0, numOffsets));
513
-
514
- case 35:
515
- case "end":
516
- return _context3.stop();
517
- }
518
- }
519
- }, _callee3, this);
520
- }));
521
-
522
- function blocksForRange(_x2, _x3, _x4) {
523
- return _blocksForRange.apply(this, arguments);
524
- }
525
-
526
- return blocksForRange;
527
- }()
528
- }]);
529
- return TabixIndex;
530
- }(_indexFile.default);
531
-
321
+ });
322
+ });
323
+ };
324
+ return TabixIndex;
325
+ }(indexFile_1.default));
532
326
  exports.default = TabixIndex;
533
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90YmkudHMiXSwibmFtZXMiOlsiVEJJX01BR0lDIiwiVEFEX0xJRFhfU0hJRlQiLCJyZWcyYmlucyIsImJlZyIsImVuZCIsImxpc3QiLCJrIiwicHVzaCIsIlRhYml4SW5kZXgiLCJyZWZOYW1lIiwib3B0cyIsInBhcnNlIiwiaW5kZXhEYXRhIiwicmVmSWQiLCJyZWZOYW1lVG9JZCIsImlkeCIsImluZGljZXMiLCJzdGF0cyIsImxpbmVDb3VudCIsInVuemlwIiwiZmlsZWhhbmRsZSIsInJlYWRGaWxlIiwiYnl0ZXMiLCJzaWduYWwiLCJyZWFkVUludDMyTEUiLCJFcnJvciIsInJlZkNvdW50IiwicmVhZEludDMyTEUiLCJmb3JtYXRGbGFncyIsImNvb3JkaW5hdGVUeXBlIiwiZm9ybWF0T3B0cyIsImZvcm1hdCIsImNvbHVtbk51bWJlcnMiLCJyZWYiLCJzdGFydCIsIm1ldGFWYWx1ZSIsImRlcHRoIiwibWF4QmluTnVtYmVyIiwibWF4UmVmTGVuZ3RoIiwibWV0YUNoYXIiLCJTdHJpbmciLCJmcm9tQ2hhckNvZGUiLCJza2lwTGluZXMiLCJuYW1lU2VjdGlvbkxlbmd0aCIsIl9wYXJzZU5hbWVCeXRlcyIsInNsaWNlIiwicmVmSWRUb05hbWUiLCJjdXJyT2Zmc2V0IiwiQXJyYXkiLCJmaWxsIiwibWFwIiwiYmluQ291bnQiLCJiaW5JbmRleCIsImoiLCJiaW4iLCJjaHVua0NvdW50IiwicGFyc2VQc2V1ZG9CaW4iLCJjaHVua3MiLCJ1IiwidiIsImZpcnN0RGF0YUxpbmUiLCJfZmluZEZpcnN0RGF0YSIsIkNodW5rIiwibGluZWFyQ291bnQiLCJsaW5lYXJJbmRleCIsIm1heEJsb2NrU2l6ZSIsIm9mZnNldCIsIkxvbmciLCJmcm9tQnl0ZXNMRSIsIm5hbWVzQnl0ZXMiLCJjdXJyUmVmSWQiLCJjdXJyTmFtZVN0YXJ0IiwiaSIsImxlbmd0aCIsInRvU3RyaW5nIiwicmVuYW1lUmVmU2VxIiwiaW5kZXhlcyIsImJpbnMiLCJtaW5PZmZzZXQiLCJWaXJ0dWFsT2Zmc2V0IiwiY29uc29sZSIsIndhcm4iLCJudW1PZmZzZXRzIiwib2ZmIiwiY29tcGFyZVRvIiwibWF4diIsIm1pbnYiLCJzb3J0IiwiYSIsImIiLCJsIiwiYmxvY2tQb3NpdGlvbiIsIkluZGV4RmlsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7OztBQUVBLElBQU1BLFNBQVMsR0FBRyxRQUFsQixDLENBQTJCOztBQUMzQixJQUFNQyxjQUFjLEdBQUcsRUFBdkI7QUFFQTs7Ozs7QUFJQSxTQUFTQyxRQUFULENBQWtCQyxHQUFsQixFQUErQkMsR0FBL0IsRUFBNEM7QUFDMUNELEVBQUFBLEdBQUcsSUFBSSxDQUFQLENBRDBDLENBQ2pDOztBQUNUQyxFQUFBQSxHQUFHLElBQUksQ0FBUDtBQUNBLE1BQU1DLElBQUksR0FBRyxDQUFDLENBQUQsQ0FBYjs7QUFDQSxPQUFLLElBQUlDLENBQUMsR0FBRyxLQUFLSCxHQUFHLElBQUksRUFBWixDQUFiLEVBQThCRyxDQUFDLElBQUksS0FBS0YsR0FBRyxJQUFJLEVBQVosQ0FBbkMsRUFBb0RFLENBQUMsSUFBSSxDQUF6RDtBQUE0REQsSUFBQUEsSUFBSSxDQUFDRSxJQUFMLENBQVVELENBQVY7QUFBNUQ7O0FBQ0EsT0FBSyxJQUFJQSxFQUFDLEdBQUcsS0FBS0gsR0FBRyxJQUFJLEVBQVosQ0FBYixFQUE4QkcsRUFBQyxJQUFJLEtBQUtGLEdBQUcsSUFBSSxFQUFaLENBQW5DLEVBQW9ERSxFQUFDLElBQUksQ0FBekQ7QUFBNERELElBQUFBLElBQUksQ0FBQ0UsSUFBTCxDQUFVRCxFQUFWO0FBQTVEOztBQUNBLE9BQUssSUFBSUEsR0FBQyxHQUFHLE1BQU1ILEdBQUcsSUFBSSxFQUFiLENBQWIsRUFBK0JHLEdBQUMsSUFBSSxNQUFNRixHQUFHLElBQUksRUFBYixDQUFwQyxFQUFzREUsR0FBQyxJQUFJLENBQTNEO0FBQThERCxJQUFBQSxJ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VUFBcEIsRUFBZ0NWLEdBQUMsSUFBSSxDQUFyQyxFQUF3QztBQUN0QyxzQkFBSVcsR0FBRyxDQUFDTyxDQUFELENBQUgsQ0FBT0wsSUFBUCxDQUFZTSxhQUFaLEtBQThCUixHQUFHLENBQUNYLEdBQUQsQ0FBSCxDQUFPYyxJQUFQLENBQVlLLGFBQTlDLEVBQ0VSLEdBQUcsQ0FBQ08sQ0FBRCxDQUFILENBQU9MLElBQVAsR0FBY0YsR0FBRyxDQUFDWCxHQUFELENBQUgsQ0FBT2EsSUFBckIsQ0FERixLQUVLO0FBQ0hLLG9CQUFBQSxDQUFDLElBQUksQ0FBTDtBQUNBUCxvQkFBQUEsR0FBRyxDQUFDTyxDQUFELENBQUgsQ0FBT0osSUFBUCxHQUFjSCxHQUFHLENBQUNYLEdBQUQsQ0FBSCxDQUFPYyxJQUFyQjtBQUNBSCxvQkFBQUEsR0FBRyxDQUFDTyxDQUFELENBQUgsQ0FBT0wsSUFBUCxHQUFjRixHQUFHLENBQUNYLEdBQUQsQ0FBSCxDQUFPYSxJQUFyQjtBQUNEO0FBQ0Y7O0FBQ0RILGdCQUFBQSxVQUFVLEdBQUdRLENBQUMsR0FBRyxDQUFqQjtrREFFT1AsR0FBRyxDQUFDdEMsS0FBSixDQUFVLENBQVYsRUFBYXFDLFVBQWIsQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBaFA2QlUsa0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgTG9uZyBmcm9tICdsb25nJ1xuaW1wb3J0IFZpcnR1YWxPZmZzZXQsIHsgZnJvbUJ5dGVzIH0gZnJvbSAnLi92aXJ0dWFsT2Zmc2V0J1xuaW1wb3J0IENodW5rIGZyb20gJy4vY2h1bmsnXG5pbXBvcnQgeyB1bnppcCB9IGZyb20gJ0BnbW9kL2JnemYtZmlsZWhhbmRsZSdcbmltcG9ydCB7IGxvbmdUb051bWJlciwgY2hlY2tBYm9ydFNpZ25hbCB9IGZyb20gJy4vdXRpbCdcbmltcG9ydCBJbmRleEZpbGUsIHsgT3B0aW9ucyB9IGZyb20gJy4vaW5kZXhGaWxlJ1xuXG5jb25zdCBUQklfTUFHSUMgPSAyMTU3ODMyNCAvLyBUQklcXDFcbmNvbnN0IFRBRF9MSURYX1NISUZUID0gMTRcblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIGxpc3Qgb2YgYmlucyB0aGF0IG1heSBvdmVybGFwIHdpdGggcmVnaW9uIFtiZWcsZW5kKSAoemVyby1iYXNlZCBoYWxmLW9wZW4pXG4gKiBAcmV0dXJucyB7QXJyYXlbbnVtYmVyXX1cbiAqL1xuZnVuY3Rpb24gcmVnMmJpbnMoYmVnOiBudW1iZXIsIGVuZDogbnVtYmVyKSB7XG4gIGJlZyArPSAxIC8vIDwgY29udmVydCB0byAxLWJhc2VkIGNsb3NlZFxuICBlbmQgLT0gMVxuICBjb25zdCBsaXN0ID0gWzBdXG4gIGZvciAobGV0IGsgPSAxICsgKGJlZyA+PiAyNik7IGsgPD0gMSArIChlbmQgPj4gMjYpOyBrICs9IDEpIGxpc3QucHVzaChrKVxuICBmb3IgKGxldCBrID0gOSArIChiZWcgPj4gMjMpOyBrIDw9IDkgKyAoZW5kID4+IDIzKTsgayArPSAxKSBsaXN0LnB1c2goaylcbiAgZm9yIChsZXQgayA9IDczICsgKGJlZyA+PiAyMCk7IGsgPD0gNzMgKyAoZW5kID4+IDIwKTsgayArPSAxKSBsaXN0LnB1c2goaylcbiAgZm9yIChsZXQgayA9IDU4NSArIChiZWcgPj4gMTcpOyBrIDw9IDU4NSArIChlbmQgPj4gMTcpOyBrICs9IDEpIGxpc3QucHVzaChrKVxuICBmb3IgKGxldCBrID0gNDY4MSArIChiZWcgPj4gMTQpOyBrIDw9IDQ2ODEgKyAoZW5kID4+IDE0KTsgayArPSAxKSBsaXN0LnB1c2goaylcbiAgcmV0dXJuIGxpc3Rcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGFiaXhJbmRleCBleHRlbmRzIEluZGV4RmlsZSB7XG4gIGFzeW5jIGxpbmVDb3VudChyZWZOYW1lOiBzdHJpbmcsIG9wdHM6IE9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGluZGV4RGF0YSA9IGF3YWl0IHRoaXMucGFyc2Uob3B0cylcbiAgICBpZiAoIWluZGV4RGF0YSkgcmV0dXJuIC0xXG4gICAgY29uc3QgcmVmSWQgPSBpbmRleERhdGEucmVmTmFtZVRvSWRbcmVmTmFtZV1cbiAgICBjb25zdCBpZHggPSBpbmRleERhdGEuaW5kaWNlc1tyZWZJZF1cbiAgICBpZiAoIWlkeCkgcmV0dXJuIC0xXG4gICAgY29uc3QgeyBzdGF0cyB9ID0gaW5kZXhEYXRhLmluZGljZXNbcmVmSWRdXG4gICAgaWYgKHN0YXRzKSByZXR1cm4gc3RhdHMubGluZUNvdW50XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBtZW1vaXplXG4gIC8vIGZldGNoIGFuZCBwYXJzZSB0aGUgaW5kZXhcbiAgYXN5bmMgX3BhcnNlKG9wdHM6IE9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGJ5dGVzID0gYXdhaXQgdW56aXAoKGF3YWl0IHRoaXMuZmlsZWhhbmRsZS5yZWFkRmlsZShvcHRzKSkgYXMgQnVmZmVyKVxuICAgIGNoZWNrQWJvcnRTaWduYWwob3B0cy5zaWduYWwpXG5cbiAgICAvLyBjaGVjayBUQkkgbWFnaWMgbnVtYmVyc1xuICAgIGlmIChieXRlcy5yZWFkVUludDMyTEUoMCkgIT09IFRCSV9NQUdJQyAvKiBcIlRCSVxcMVwiICovKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBhIFRCSSBmaWxlJylcbiAgICAgIC8vIFRPRE86IGRvIHdlIG5lZWQgdG8gc3VwcG9ydCBiaWctZW5kaWFuIFRCSSBmaWxlcz9cbiAgICB9XG5cbiAgICAvLyBudW1iZXIgb2YgcmVmZXJlbmNlIHNlcXVlbmNlcyBpbiB0aGUgaW5kZXhcbiAgICBjb25zdCByZWZDb3VudCA9IGJ5dGVzLnJlYWRJbnQzMkxFKDQpXG4gICAgY29uc3QgZm9ybWF0RmxhZ3MgPSBieXRlcy5yZWFkSW50MzJMRSg4KVxuICAgIGNvbnN0IGNvb3JkaW5hdGVUeXBlID1cbiAgICAgIGZvcm1hdEZsYWdzICYgMHgxMDAwMCA/ICd6ZXJvLWJhc2VkLWhhbGYtb3BlbicgOiAnMS1iYXNlZC1jbG9zZWQnXG4gICAgY29uc3QgZm9ybWF0T3B0czogeyBba2V5OiBudW1iZXJdOiBzdHJpbmcgfSA9IHtcbiAgICAgIDA6ICdnZW5lcmljJyxcbiAgICAgIDE6ICdTQU0nLFxuICAgICAgMjogJ1ZDRicsXG4gICAgfVxuICAgIGNvbnN0IGZvcm1hdCA9IGZvcm1hdE9wdHNbZm9ybWF0RmxhZ3MgJiAweGZdXG4gICAgaWYgKCFmb3JtYXQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgVGFiaXggcHJlc2V0IGZvcm1hdCBmbGFncyAke2Zvcm1hdEZsYWdzfWApXG4gICAgY29uc3QgY29sdW1uTnVtYmVycyA9IHtcbiAgICAgIHJlZjogYnl0ZXMucmVhZEludDMyTEUoMTIpLFxuICAgICAgc3RhcnQ6IGJ5dGVzLnJlYWRJbnQzMkxFKDE2KSxcbiAgICAgIGVuZDogYnl0ZXMucmVhZEludDMyTEUoMjApLFxuICAgIH1cbiAgICBjb25zdCBtZXRhVmFsdWUgPSBieXRlcy5yZWFkSW50MzJMRSgyNClcbiAgICBjb25zdCBkZXB0aCA9IDVcbiAgICBjb25zdCBtYXhCaW5OdW1iZXIgPSAoKDEgPDwgKChkZXB0aCArIDEpICogMykpIC0gMSkgLyA3XG4gICAgY29uc3QgbWF4UmVmTGVuZ3RoID0gMiAqKiAoMTQgKyBkZXB0aCAqIDMpXG4gICAgY29uc3QgbWV0YUNoYXIgPSBtZXRhVmFsdWUgPyBTdHJpbmcuZnJvbUNoYXJDb2RlKG1ldGFWYWx1ZSkgOiBudWxsXG4gICAgY29uc3Qgc2tpcExpbmVzID0gYnl0ZXMucmVhZEludDMyTEUoMjgpXG5cbiAgICAvLyByZWFkIHNlcXVlbmNlIGRpY3Rpb25hcnlcbiAgICBjb25zdCBuYW1lU2VjdGlvbkxlbmd0aCA9IGJ5dGVzLnJlYWRJbnQzMkxFKDMyKVxuICAgIGNvbnN0IHsgcmVmTmFtZVRvSWQsIHJlZklkVG9OYW1lIH0gPSB0aGlzLl9wYXJzZU5hbWVCeXRlcyhcbiAgICAgIGJ5dGVzLnNsaWNlKDM2LCAzNiArIG5hbWVTZWN0aW9uTGVuZ3RoKSxcbiAgICApXG5cbiAgICAvLyByZWFkIHRoZSBpbmRleGVzIGZvciBlYWNoIHJlZmVyZW5jZSBzZXF1ZW5jZVxuICAgIGxldCBjdXJyT2Zmc2V0ID0gMzYgKyBuYW1lU2VjdGlvbkxlbmd0aFxuICAgIGxldCBmaXJzdERhdGFMaW5lOiBWaXJ0dWFsT2Zmc2V0IHwgdW5kZWZpbmVkXG4gICAgY29uc3QgaW5kaWNlcyA9IG5ldyBBcnJheShyZWZDb3VudCkuZmlsbCgwKS5tYXAoKCkgPT4ge1xuICAgICAgLy8gdGhlIGJpbm5pbmcgaW5kZXhcbiAgICAgIGNvbnN0IGJpbkNvdW50ID0gYnl0ZXMucmVhZEludDMyTEUoY3Vyck9mZnNldClcbiAgICAgIGN1cnJPZmZzZXQgKz0gNFxuICAgICAgY29uc3QgYmluSW5kZXg6IHsgW2tleTogbnVtYmVyXTogQ2h1bmtbXSB9ID0ge31cbiAgICAgIGxldCBzdGF0c1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBiaW5Db3VudDsgaiArPSAxKSB7XG4gICAgICAgIGNvbnN0IGJpbiA9IGJ5dGVzLnJlYWRVSW50MzJMRShjdXJyT2Zmc2V0KVxuICAgICAgICBjdXJyT2Zmc2V0ICs9IDRcbiAgICAgICAgaWYgKGJpbiA+IG1heEJpbk51bWJlciArIDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAndGFiaXggaW5kZXggY29udGFpbnMgdG9vIG1hbnkgYmlucywgcGxlYXNlIHVzZSBhIENTSSBpbmRleCcsXG4gICAgICAgICAgKVxuICAgICAgICB9IGVsc2UgaWYgKGJpbiA9PT0gbWF4QmluTnVtYmVyICsgMSkge1xuICAgICAgICAgIGNvbnN0IGNodW5rQ291bnQgPSBieXRlcy5yZWFkSW50MzJMRShjdXJyT2Zmc2V0KVxuICAgICAgICAgIGN1cnJPZmZzZXQgKz0gNFxuICAgICAgICAgIGlmIChjaHVua0NvdW50ID09PSAyKSB7XG4gICAgICAgICAgICBzdGF0cyA9IHRoaXMucGFyc2VQc2V1ZG9CaW4oYnl0ZXMsIGN1cnJPZmZzZXQpXG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJPZmZzZXQgKz0gMTYgKiBjaHVua0NvdW50XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgY2h1bmtDb3VudCA9IGJ5dGVzLnJlYWRJbnQzMkxFKGN1cnJPZmZzZXQpXG4gICAgICAgICAgY3Vyck9mZnNldCArPSA0XG4gICAgICAgICAgY29uc3QgY2h1bmtzID0gbmV3IEFycmF5KGNodW5rQ291bnQpXG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBjaHVua0NvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHUgPSBmcm9tQnl0ZXMoYnl0ZXMsIGN1cnJPZmZzZXQpXG4gICAgICAgICAgICBjb25zdCB2ID0gZnJvbUJ5dGVzKGJ5dGVzLCBjdXJyT2Zmc2V0ICsgOClcbiAgICAgICAgICAgIGN1cnJPZmZzZXQgKz0gMTZcbiAgICAgICAgICAgIGZpcnN0RGF0YUxpbmUgPSB0aGlzLl9maW5kRmlyc3REYXRhKGZpcnN0RGF0YUxpbmUsIHUpXG4gICAgICAgICAgICBjaHVua3Nba10gPSBuZXcgQ2h1bmsodSwgdiwgYmluKVxuICAgICAgICAgIH1cbiAgICAgICAgICBiaW5JbmRleFtiaW5dID0gY2h1bmtzXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gdGhlIGxpbmVhciBpbmRleFxuICAgICAgY29uc3QgbGluZWFyQ291bnQgPSBieXRlcy5yZWFkSW50MzJMRShjdXJyT2Zmc2V0KVxuICAgICAgY3Vyck9mZnNldCArPSA0XG4gICAgICBjb25zdCBsaW5lYXJJbmRleCA9IG5ldyBBcnJheShsaW5lYXJDb3VudClcbiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgbGluZWFyQ291bnQ7IGsgKz0gMSkge1xuICAgICAgICBsaW5lYXJJbmRleFtrXSA9IGZyb21CeXRlcyhieXRlcywgY3Vyck9mZnNldClcbiAgICAgICAgY3Vyck9mZnNldCArPSA4XG4gICAgICAgIGZpcnN0RGF0YUxpbmUgPSB0aGlzLl9maW5kRmlyc3REYXRhKGZpcnN0RGF0YUxpbmUsIGxpbmVhckluZGV4W2tdKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHsgYmluSW5kZXgsIGxpbmVhckluZGV4LCBzdGF0cyB9XG4gICAgfSlcblxuICAgIHJldHVybiB7XG4gICAgICBpbmRpY2VzLFxuICAgICAgbWV0YUNoYXIsXG4gICAgICBtYXhCaW5OdW1iZXIsXG4gICAgICBtYXhSZWZMZW5ndGgsXG4gICAgICBza2lwTGluZXMsXG4gICAgICBmaXJzdERhdGFMaW5lLFxuICAgICAgY29sdW1uTnVtYmVycyxcbiAgICAgIGNvb3JkaW5hdGVUeXBlLFxuICAgICAgZm9ybWF0LFxuICAgICAgcmVmSWRUb05hbWUsXG4gICAgICByZWZOYW1lVG9JZCxcbiAgICAgIG1heEJsb2NrU2l6ZTogMSA8PCAxNixcbiAgICB9XG4gIH1cblxuICBwYXJzZVBzZXVkb0JpbihieXRlczogQnVmZmVyLCBvZmZzZXQ6IG51bWJlcikge1xuICAgIGNvbnN0IGxpbmVDb3VudCA9IGxvbmdUb051bWJlcihcbiAgICAgIExvbmcuZnJvbUJ5dGVzTEUoXG4gICAgICAgIChieXRlcy5zbGljZShvZmZzZXQgKyAxNiwgb2Zmc2V0ICsgMjQpIGFzIHVua25vd24pIGFzIG51bWJlcltdLFxuICAgICAgICB0cnVlLFxuICAgICAgKSxcbiAgICApXG4gICAgcmV0dXJuIHsgbGluZUNvdW50IH1cbiAgfVxuXG4gIF9wYXJzZU5hbWVCeXRlcyhuYW1lc0J5dGVzOiBCdWZmZXIpIHtcbiAgICBsZXQgY3VyclJlZklkID0gMFxuICAgIGxldCBjdXJyTmFtZVN0YXJ0ID0gMFxuICAgIGNvbnN0IHJlZklkVG9OYW1lOiBzdHJpbmdbXSA9IFtdXG4gICAgY29uc3QgcmVmTmFtZVRvSWQ6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB7fVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmFtZXNCeXRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKCFuYW1lc0J5dGVzW2ldKSB7XG4gICAgICAgIGlmIChjdXJyTmFtZVN0YXJ0IDwgaSkge1xuICAgICAgICAgIGxldCByZWZOYW1lID0gbmFtZXNCeXRlcy50b1N0cmluZygndXRmOCcsIGN1cnJOYW1lU3RhcnQsIGkpXG4gICAgICAgICAgcmVmTmFtZSA9IHRoaXMucmVuYW1lUmVmU2VxKHJlZk5hbWUpXG4gICAgICAgICAgcmVmSWRUb05hbWVbY3VyclJlZklkXSA9IHJlZk5hbWVcbiAgICAgICAgICByZWZOYW1lVG9JZFtyZWZOYW1lXSA9IGN1cnJSZWZJZFxuICAgICAgICB9XG4gICAgICAgIGN1cnJOYW1lU3RhcnQgPSBpICsgMVxuICAgICAgICBjdXJyUmVmSWQgKz0gMVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyByZWZOYW1lVG9JZCwgcmVmSWRUb05hbWUgfVxuICB9XG5cbiAgYXN5bmMgYmxvY2tzRm9yUmFuZ2UoXG4gICAgcmVmTmFtZTogc3RyaW5nLFxuICAgIGJlZzogbnVtYmVyLFxuICAgIGVuZDogbnVtYmVyLFxuICAgIG9wdHM6IE9wdGlvbnMgPSB7fSxcbiAgKSB7XG4gICAgaWYgKGJlZyA8IDApIGJlZyA9IDBcblxuICAgIGNvbnN0IGluZGV4RGF0YSA9IGF3YWl0IHRoaXMucGFyc2Uob3B0cylcbiAgICBpZiAoIWluZGV4RGF0YSkgcmV0dXJuIFtdXG4gICAgY29uc3QgcmVmSWQgPSBpbmRleERhdGEucmVmTmFtZVRvSWRbcmVmTmFtZV1cbiAgICBjb25zdCBpbmRleGVzID0gaW5kZXhEYXRhLmluZGljZXNbcmVmSWRdXG4gICAgaWYgKCFpbmRleGVzKSByZXR1cm4gW11cblxuICAgIGNvbnN0IHsgbGluZWFySW5kZXgsIGJpbkluZGV4IH0gPSBpbmRleGVzXG5cbiAgICBjb25zdCBiaW5zID0gcmVnMmJpbnMoYmVnLCBlbmQpXG5cbiAgICBjb25zdCBtaW5PZmZzZXQgPSBsaW5lYXJJbmRleC5sZW5ndGhcbiAgICAgID8gbGluZWFySW5kZXhbXG4gICAgICAgICAgYmVnID4+IFRBRF9MSURYX1NISUZUID49IGxpbmVhckluZGV4Lmxlbmd0aFxuICAgICAgICAgICAgPyBsaW5lYXJJbmRleC5sZW5ndGggLSAxXG4gICAgICAgICAgICA6IGJlZyA+PiBUQURfTElEWF9TSElGVFxuICAgICAgICBdXG4gICAgICA6IG5ldyBWaXJ0dWFsT2Zmc2V0KDAsIDApXG4gICAgaWYgKCFtaW5PZmZzZXQpIHtcbiAgICAgIGNvbnNvbGUud2FybigncXVlcnlpbmcgb3V0c2lkZSBvZiBwb3NzaWJsZSB0YWJpeCByYW5nZScpXG4gICAgICByZXR1cm4gW11cbiAgICB9XG5cbiAgICBsZXQgbFxuICAgIGxldCBudW1PZmZzZXRzID0gMFxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmlucy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKGJpbkluZGV4W2JpbnNbaV1dKSBudW1PZmZzZXRzICs9IGJpbkluZGV4W2JpbnNbaV1dLmxlbmd0aFxuICAgIH1cblxuICAgIGlmIChudW1PZmZzZXRzID09PSAwKSByZXR1cm4gW11cblxuICAgIGxldCBvZmYgPSBbXVxuICAgIG51bU9mZnNldHMgPSAwXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBiaW5zLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBjb25zdCBjaHVua3MgPSBiaW5JbmRleFtiaW5zW2ldXVxuICAgICAgaWYgKGNodW5rcylcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjaHVua3MubGVuZ3RoOyBqICs9IDEpXG4gICAgICAgICAgaWYgKG1pbk9mZnNldC5jb21wYXJlVG8oY2h1bmtzW2pdLm1heHYpIDwgMCkge1xuICAgICAgICAgICAgb2ZmW251bU9mZnNldHNdID0gbmV3IENodW5rKFxuICAgICAgICAgICAgICBjaHVua3Nbal0ubWludixcbiAgICAgICAgICAgICAgY2h1bmtzW2pdLm1heHYsXG4gICAgICAgICAgICAgIGNodW5rc1tqXS5iaW4sXG4gICAgICAgICAgICApXG4gICAgICAgICAgICBudW1PZmZzZXRzICs9IDFcbiAgICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFvZmYubGVuZ3RoKSByZXR1cm4gW11cblxuICAgIG9mZiA9IG9mZi5zb3J0KChhLCBiKSA9PiBhLmNvbXBhcmVUbyhiKSlcblxuICAgIC8vIHJlc29sdmUgY29tcGxldGVseSBjb250YWluZWQgYWRqYWNlbnQgYmxvY2tzXG4gICAgbCA9IDBcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8IG51bU9mZnNldHM7IGkgKz0gMSkge1xuICAgICAgaWYgKG9mZltsXS5tYXh2LmNvbXBhcmVUbyhvZmZbaV0ubWF4dikgPCAwKSB7XG4gICAgICAgIGwgKz0gMVxuICAgICAgICBvZmZbbF0ubWludiA9IG9mZltpXS5taW52XG4gICAgICAgIG9mZltsXS5tYXh2ID0gb2ZmW2ldLm1heHZcbiAgICAgIH1cbiAgICB9XG4gICAgbnVtT2Zmc2V0cyA9IGwgKyAxXG5cbiAgICAvLyByZXNvbHZlIG92ZXJsYXBzIGJldHdlZW4gYWRqYWNlbnQgYmxvY2tzOyB0aGlzIG1heSBoYXBwZW4gZHVlIHRvIHRoZSBtZXJnZSBpbiBpbmRleGluZ1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgbnVtT2Zmc2V0czsgaSArPSAxKSB7XG4gICAgICBpZiAob2ZmW2kgLSAxXS5tYXh2LmNvbXBhcmVUbyhvZmZbaV0ubWludikgPj0gMCkge1xuICAgICAgICBvZmZbaSAtIDFdLm1heHYgPSBvZmZbaV0ubWludlxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIG1lcmdlIGFkamFjZW50IGJsb2Nrc1xuICAgIGwgPSAwXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBudW1PZmZzZXRzOyBpICs9IDEpIHtcbiAgICAgIGlmIChvZmZbbF0ubWF4di5ibG9ja1Bvc2l0aW9uID09PSBvZmZbaV0ubWludi5ibG9ja1Bvc2l0aW9uKVxuICAgICAgICBvZmZbbF0ubWF4diA9IG9mZltpXS5tYXh2XG4gICAgICBlbHNlIHtcbiAgICAgICAgbCArPSAxXG4gICAgICAgIG9mZltsXS5taW52ID0gb2ZmW2ldLm1pbnZcbiAgICAgICAgb2ZmW2xdLm1heHYgPSBvZmZbaV0ubWF4dlxuICAgICAgfVxuICAgIH1cbiAgICBudW1PZmZzZXRzID0gbCArIDFcblxuICAgIHJldHVybiBvZmYuc2xpY2UoMCwgbnVtT2Zmc2V0cylcbiAgfVxufVxuIl19