@gmod/tabix 1.5.0 → 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,503 +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 _getIterator2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/get-iterator"));
16
-
17
- var _isArray = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/is-array"));
18
-
19
- var _iterator2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/symbol/iterator"));
20
-
21
- var _symbol = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/symbol"));
22
-
23
- var _from = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/array/from"));
24
-
25
- var _construct = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/reflect/construct"));
26
-
27
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
28
-
29
- var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
30
-
31
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
32
-
33
- var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
34
-
35
- var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
36
-
37
- var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
38
-
39
- var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
40
-
41
- var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
42
-
43
- var _long = _interopRequireDefault(require("long"));
44
-
45
- var _virtualOffset = _interopRequireWildcard(require("./virtualOffset"));
46
-
47
- var _chunk = _interopRequireDefault(require("./chunk"));
48
-
49
- var _bgzfFilehandle = require("@gmod/bgzf-filehandle");
50
-
51
- var _util = require("./util");
52
-
53
- var _indexFile = _interopRequireDefault(require("./indexFile"));
54
-
55
- function _createForOfIteratorHelper(o) { if (typeof _symbol.default === "undefined" || o[_iterator2.default] == null) { if ((0, _isArray.default)(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = (0, _getIterator2.default)(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
56
-
57
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return (0, _from.default)(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
58
-
59
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
60
-
61
- 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); }; }
62
-
63
- 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; } }
64
-
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"));
65
82
  var TBI_MAGIC = 21578324; // TBI\1
66
-
67
83
  var TAD_LIDX_SHIFT = 14;
68
84
  /**
69
85
  * calculate the list of bins that may overlap with region [beg,end) (zero-based half-open)
70
- * @returns {Array[number]}
71
86
  */
72
-
73
87
  function reg2bins(beg, end) {
74
- beg += 1; // < convert to 1-based closed
75
-
76
- end -= 1;
77
- return [[0, 0], [1 + (beg >> 26), 1 + (end >> 26)], [9 + (beg >> 23), 9 + (end >> 23)], [73 + (beg >> 20), 73 + (end >> 20)], [585 + (beg >> 17), 585 + (end >> 17)], [4681 + (beg >> 14), 4681 + (end >> 14)]];
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
+ ];
78
98
  }
79
-
80
- var TabixIndex = /*#__PURE__*/function (_IndexFile) {
81
- (0, _inherits2.default)(TabixIndex, _IndexFile);
82
-
83
- var _super = _createSuper(TabixIndex);
84
-
85
- function TabixIndex() {
86
- (0, _classCallCheck2.default)(this, TabixIndex);
87
- return _super.apply(this, arguments);
88
- }
89
-
90
- (0, _createClass2.default)(TabixIndex, [{
91
- key: "lineCount",
92
- value: function () {
93
- var _lineCount = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(refName) {
94
- var opts,
95
- indexData,
96
- refId,
97
- idx,
98
- stats,
99
- _args = arguments;
100
- return _regenerator.default.wrap(function _callee$(_context) {
101
- while (1) {
102
- switch (_context.prev = _context.next) {
103
- case 0:
104
- opts = _args.length > 1 && _args[1] !== undefined ? _args[1] : {};
105
- _context.next = 3;
106
- return this.parse(opts);
107
-
108
- case 3:
109
- indexData = _context.sent;
110
-
111
- if (indexData) {
112
- _context.next = 6;
113
- break;
114
- }
115
-
116
- return _context.abrupt("return", -1);
117
-
118
- case 6:
119
- refId = indexData.refNameToId[refName];
120
- idx = indexData.indices[refId];
121
-
122
- if (idx) {
123
- _context.next = 10;
124
- break;
125
- }
126
-
127
- return _context.abrupt("return", -1);
128
-
129
- case 10:
130
- stats = indexData.indices[refId].stats;
131
-
132
- if (!stats) {
133
- _context.next = 13;
134
- 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];
135
126
  }
136
-
137
- return _context.abrupt("return", stats.lineCount);
138
-
139
- case 13:
140
- return _context.abrupt("return", -1);
141
-
142
- case 14:
143
- case "end":
144
- return _context.stop();
145
- }
146
- }
147
- }, _callee, this);
148
- }));
149
-
150
- function lineCount(_x) {
151
- return _lineCount.apply(this, arguments);
152
- }
153
-
154
- return lineCount;
155
- }() // memoize
127
+ });
128
+ });
129
+ };
130
+ // memoize
156
131
  // fetch and parse the index
157
-
158
- }, {
159
- key: "_parse",
160
- value: function () {
161
- var _parse2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {
162
- var _this = this;
163
-
164
- var opts,
165
- bytes,
166
- refCount,
167
- formatFlags,
168
- coordinateType,
169
- formatOpts,
170
- format,
171
- columnNumbers,
172
- metaValue,
173
- depth,
174
- maxBinNumber,
175
- maxRefLength,
176
- metaChar,
177
- skipLines,
178
- nameSectionLength,
179
- _this$_parseNameBytes,
180
- refNameToId,
181
- refIdToName,
182
- currOffset,
183
- firstDataLine,
184
- indices,
185
- _args2 = arguments;
186
-
187
- return _regenerator.default.wrap(function _callee2$(_context2) {
188
- while (1) {
189
- switch (_context2.prev = _context2.next) {
190
- case 0:
191
- opts = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {};
192
- _context2.t0 = _bgzfFilehandle.unzip;
193
- _context2.next = 4;
194
- return this.filehandle.readFile(opts);
195
-
196
- case 4:
197
- _context2.t1 = _context2.sent;
198
- _context2.next = 7;
199
- return (0, _context2.t0)(_context2.t1);
200
-
201
- case 7:
202
- bytes = _context2.sent;
203
- (0, _util.checkAbortSignal)(opts.signal); // check TBI magic numbers
204
-
205
- if (!(bytes.readUInt32LE(0) !== TBI_MAGIC
206
- /* "TBI\1" */
207
- )) {
208
- _context2.next = 11;
209
- 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
+ }];
210
236
  }
211
-
212
- throw new Error('Not a TBI file');
213
-
214
- case 11:
215
- // number of reference sequences in the index
216
- refCount = bytes.readInt32LE(4);
217
- formatFlags = bytes.readInt32LE(8);
218
- coordinateType = formatFlags & 0x10000 ? 'zero-based-half-open' : '1-based-closed';
219
- formatOpts = {
220
- 0: 'generic',
221
- 1: 'SAM',
222
- 2: 'VCF'
223
- };
224
- format = formatOpts[formatFlags & 0xf];
225
-
226
- if (format) {
227
- _context2.next = 18;
228
- 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;
229
256
  }
230
-
231
- throw new Error("invalid Tabix preset format flags ".concat(formatFlags));
232
-
233
- case 18:
234
- columnNumbers = {
235
- ref: bytes.readInt32LE(12),
236
- start: bytes.readInt32LE(16),
237
- end: bytes.readInt32LE(20)
238
- };
239
- metaValue = bytes.readInt32LE(24);
240
- depth = 5;
241
- maxBinNumber = ((1 << (depth + 1) * 3) - 1) / 7;
242
- maxRefLength = Math.pow(2, 14 + depth * 3);
243
- metaChar = metaValue ? String.fromCharCode(metaValue) : null;
244
- skipLines = bytes.readInt32LE(28); // read sequence dictionary
245
-
246
- nameSectionLength = bytes.readInt32LE(32);
247
- _this$_parseNameBytes = this._parseNameBytes(bytes.slice(36, 36 + nameSectionLength)), refNameToId = _this$_parseNameBytes.refNameToId, refIdToName = _this$_parseNameBytes.refIdToName; // read the indexes for each reference sequence
248
-
249
- currOffset = 36 + nameSectionLength;
250
- indices = new Array(refCount).fill(0).map(function () {
251
- // the binning index
252
- var binCount = bytes.readInt32LE(currOffset);
253
- currOffset += 4;
254
- var binIndex = {};
255
- var stats;
256
-
257
- for (var j = 0; j < binCount; j += 1) {
258
- var bin = bytes.readUInt32LE(currOffset);
259
- currOffset += 4;
260
-
261
- if (bin > maxBinNumber + 1) {
262
- throw new Error('tabix index contains too many bins, please use a CSI index');
263
- } else if (bin === maxBinNumber + 1) {
264
- var chunkCount = bytes.readInt32LE(currOffset);
265
- currOffset += 4;
266
-
267
- if (chunkCount === 2) {
268
- stats = _this.parsePseudoBin(bytes, currOffset);
269
- }
270
-
271
- currOffset += 16 * chunkCount;
272
- } else {
273
- var _chunkCount = bytes.readInt32LE(currOffset);
274
-
275
- currOffset += 4;
276
- var chunks = new Array(_chunkCount);
277
-
278
- for (var k = 0; k < _chunkCount; k += 1) {
279
- var u = (0, _virtualOffset.fromBytes)(bytes, currOffset);
280
- var v = (0, _virtualOffset.fromBytes)(bytes, currOffset + 8);
281
- currOffset += 16;
282
- firstDataLine = _this._findFirstData(firstDataLine, u);
283
- chunks[k] = new _chunk.default(u, v, bin);
284
- }
285
-
286
- binIndex[bin] = chunks;
287
- }
288
- } // the linear index
289
-
290
-
291
- var linearCount = bytes.readInt32LE(currOffset);
292
- currOffset += 4;
293
- var linearIndex = new Array(linearCount);
294
-
295
- for (var _k = 0; _k < linearCount; _k += 1) {
296
- linearIndex[_k] = (0, _virtualOffset.fromBytes)(bytes, currOffset);
297
- currOffset += 8;
298
- firstDataLine = _this._findFirstData(firstDataLine, linearIndex[_k]);
299
- }
300
-
301
- return {
302
- binIndex: binIndex,
303
- linearIndex: linearIndex,
304
- stats: stats
305
- };
306
- });
307
- return _context2.abrupt("return", {
308
- indices: indices,
309
- metaChar: metaChar,
310
- maxBinNumber: maxBinNumber,
311
- maxRefLength: maxRefLength,
312
- skipLines: skipLines,
313
- firstDataLine: firstDataLine,
314
- columnNumbers: columnNumbers,
315
- coordinateType: coordinateType,
316
- format: format,
317
- refIdToName: refIdToName,
318
- refNameToId: refNameToId,
319
- maxBlockSize: 1 << 16
320
- });
321
-
322
- case 30:
323
- case "end":
324
- return _context2.stop();
257
+ currNameStart = i + 1;
258
+ currRefId += 1;
325
259
  }
326
- }
327
- }, _callee2, this);
328
- }));
329
-
330
- function _parse() {
331
- return _parse2.apply(this, arguments);
332
- }
333
-
334
- return _parse;
335
- }()
336
- }, {
337
- key: "parsePseudoBin",
338
- value: function parsePseudoBin(bytes, offset) {
339
- var lineCount = (0, _util.longToNumber)(_long.default.fromBytesLE(bytes.slice(offset + 16, offset + 24), true));
340
- return {
341
- lineCount: lineCount
342
- };
343
- }
344
- }, {
345
- key: "_parseNameBytes",
346
- value: function _parseNameBytes(namesBytes) {
347
- var currRefId = 0;
348
- var currNameStart = 0;
349
- var refIdToName = [];
350
- var refNameToId = {};
351
-
352
- for (var i = 0; i < namesBytes.length; i += 1) {
353
- if (!namesBytes[i]) {
354
- if (currNameStart < i) {
355
- var refName = namesBytes.toString('utf8', currNameStart, i);
356
- refName = this.renameRefSeq(refName);
357
- refIdToName[currRefId] = refName;
358
- refNameToId[refName] = currRefId;
359
- }
360
-
361
- currNameStart = i + 1;
362
- currRefId += 1;
363
260
  }
364
- }
365
-
366
- return {
367
- refNameToId: refNameToId,
368
- refIdToName: refIdToName
369
- };
370
- }
371
- }, {
372
- key: "blocksForRange",
373
- value: function () {
374
- var _blocksForRange = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3(refName, min, max) {
375
- var opts,
376
- indexData,
377
- refId,
378
- ba,
379
- minOffset,
380
- overlappingBins,
381
- chunks,
382
- _iterator,
383
- _step,
384
- _step$value,
385
- start,
386
- end,
387
- bin,
388
- binChunks,
389
- c,
390
- nintv,
391
- lowest,
392
- minLin,
393
- maxLin,
394
- i,
395
- vp,
396
- _args3 = arguments;
397
-
398
- return _regenerator.default.wrap(function _callee3$(_context3) {
399
- while (1) {
400
- switch (_context3.prev = _context3.next) {
401
- case 0:
402
- opts = _args3.length > 3 && _args3[3] !== undefined ? _args3[3] : {};
403
-
404
- if (min < 0) {
405
- min = 0;
406
- }
407
-
408
- _context3.next = 4;
409
- return this.parse(opts);
410
-
411
- case 4:
412
- indexData = _context3.sent;
413
-
414
- if (indexData) {
415
- _context3.next = 7;
416
- break;
417
- }
418
-
419
- return _context3.abrupt("return", []);
420
-
421
- case 7:
422
- refId = indexData.refNameToId[refName];
423
- ba = indexData.indices[refId];
424
-
425
- if (ba) {
426
- _context3.next = 11;
427
- break;
428
- }
429
-
430
- return _context3.abrupt("return", []);
431
-
432
- case 11:
433
- minOffset = ba.linearIndex.length ? ba.linearIndex[min >> TAD_LIDX_SHIFT >= ba.linearIndex.length ? ba.linearIndex.length - 1 : min >> TAD_LIDX_SHIFT] : new _virtualOffset.default(0, 0);
434
-
435
- if (!minOffset) {
436
- console.warn('querying outside of possible tabix range');
437
- } // const { linearIndex, binIndex } = indexes
438
-
439
-
440
- overlappingBins = reg2bins(min, max); // List of bin #s that overlap min, max
441
-
442
- chunks = []; // Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned
443
-
444
- _iterator = _createForOfIteratorHelper(overlappingBins);
445
-
446
- try {
447
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
448
- _step$value = (0, _slicedToArray2.default)(_step.value, 2), start = _step$value[0], end = _step$value[1];
449
-
450
- for (bin = start; bin <= end; bin++) {
451
- if (ba.binIndex[bin]) {
452
- binChunks = ba.binIndex[bin];
453
-
454
- for (c = 0; c < binChunks.length; ++c) {
455
- chunks.push(new _chunk.default(binChunks[c].minv, binChunks[c].maxv, bin));
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;
456
272
  }
457
- }
458
- }
459
- } // Use the linear index to find minimum file position of chunks that could contain alignments in the region
460
-
461
- } catch (err) {
462
- _iterator.e(err);
463
- } finally {
464
- _iterator.f();
465
- }
466
-
467
- nintv = ba.linearIndex.length;
468
- lowest = null;
469
- minLin = Math.min(min >> 14, nintv - 1);
470
- maxLin = Math.min(max >> 14, nintv - 1);
471
-
472
- for (i = minLin; i <= maxLin; ++i) {
473
- vp = ba.linearIndex[i];
474
-
475
- if (vp) {
476
- if (!lowest || vp.compareTo(lowest) < 0) {
477
- lowest = vp;
478
- }
479
- }
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)];
480
320
  }
481
-
482
- return _context3.abrupt("return", (0, _util.optimizeChunks)(chunks, lowest));
483
-
484
- case 23:
485
- case "end":
486
- return _context3.stop();
487
- }
488
- }
489
- }, _callee3, this);
490
- }));
491
-
492
- function blocksForRange(_x2, _x3, _x4) {
493
- return _blocksForRange.apply(this, arguments);
494
- }
495
-
496
- return blocksForRange;
497
- }()
498
- }]);
499
- return TabixIndex;
500
- }(_indexFile.default);
501
-
321
+ });
322
+ });
323
+ };
324
+ return TabixIndex;
325
+ }(indexFile_1.default));
502
326
  exports.default = TabixIndex;
503
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy90YmkudHMiXSwibmFtZXMiOlsiVEJJX01BR0lDIiwiVEFEX0xJRFhfU0hJRlQiLCJyZWcyYmlucyIsImJlZyIsImVuZCIsIlRhYml4SW5kZXgiLCJyZWZOYW1lIiwib3B0cyIsInBhcnNlIiwiaW5kZXhEYXRhIiwicmVmSWQiLCJyZWZOYW1lVG9JZCIsImlkeCIsImluZGljZXMiLCJzdGF0cyIsImxpbmVDb3VudCIsInVuemlwIiwiZmlsZWhhbmRsZSIsInJlYWRGaWxlIiwiYnl0ZXMiLCJzaWduYWwiLCJyZWFkVUludDMyTEUiLCJFcnJvciIsInJlZkNvdW50IiwicmVhZEludDMyTEUiLCJmb3JtYXRGbGFncyIsImNvb3JkaW5hdGVUeXBlIiwiZm9ybWF0T3B0cyIsImZvcm1hdCIsImNvbHVtbk51bWJlcnMiLCJyZWYiLCJzdGFydCIsIm1ldGFWYWx1ZSIsImRlcHRoIiwibWF4QmluTnVtYmVyIiwibWF4UmVmTGVuZ3RoIiwibWV0YUNoYXIiLCJTdHJpbmciLCJmcm9tQ2hhckNvZGUiLCJza2lwTGluZXMiLCJuYW1lU2VjdGlvbkxlbmd0aCIsIl9wYXJzZU5hbWVCeXRlcyIsInNsaWNlIiwicmVmSWRUb05hbWUiLCJjdXJyT2Zmc2V0IiwiQXJyYXkiLCJmaWxsIiwibWFwIiwiYmluQ291bnQiLCJiaW5JbmRleCIsImoiLCJiaW4iLCJjaHVua0NvdW50IiwicGFyc2VQc2V1ZG9CaW4iLCJjaHVua3MiLCJrIiwidSIsInYiLCJmaXJzdERhdGFMaW5lIiwiX2ZpbmRGaXJzdERhdGEiLCJDaHVuayIsImxpbmVhckNvdW50IiwibGluZWFySW5kZXgiLCJtYXhCbG9ja1NpemUiLCJvZmZzZXQiLCJMb25nIiwiZnJvbUJ5dGVzTEUiLCJuYW1lc0J5dGVzIiwiY3VyclJlZklkIiwiY3Vyck5hbWVTdGFydCIsImkiLCJsZW5ndGgiLCJ0b1N0cmluZyIsInJlbmFtZVJlZlNlcSIsIm1pbiIsIm1heCIsImJhIiwibWluT2Zmc2V0IiwiVmlydHVhbE9mZnNldCIsImNvbnNvbGUiLCJ3YXJuIiwib3ZlcmxhcHBpbmdCaW5zIiwiYmluQ2h1bmtzIiwiYyIsInB1c2giLCJtaW52IiwibWF4diIsIm5pbnR2IiwibG93ZXN0IiwibWluTGluIiwiTWF0aCIsIm1heExpbiIsInZwIiwiY29tcGFyZVRvIiwiSW5kZXhGaWxlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7O0FBRUEsSUFBTUEsU0FBUyxHQUFHLFFBQWxCLEMsQ0FBMkI7O0FBQzNCLElBQU1DLGNBQWMsR0FBRyxFQUF2QjtBQUVBOzs7OztBQUlBLFNBQVNDLFFBQVQsQ0FBa0JDLEdBQWxCLEVBQStCQyxHQUEvQixFQUE0QztBQUMxQ0QsRUFBQUEsR0FBRyxJQUFJLENBQVAsQ0FEMEMsQ0FDakM7O0FBQ1RDLEVBQUFBLEdBQUcsSUFBSSxDQUFQO0FBQ0EsU0FBTyxDQUNMLENBQUMsQ0FBRCxFQUFJLENBQUosQ0FESyxFQUVMLENBQUMsS0FBS0QsR0FBRyxJQUFJLEVBQVosQ0FBRCxFQUFrQixLQUFLQyxHQUFHLElBQUksRUFBWixDQUFsQixDQUZLLEVBR0wsQ0FBQyxLQUFLRCxHQUFHLElBQUksRUFBWixDQUFELEVBQWtCLEtBQUtDLEdBQUcsSUFBSSxFQUFaLENBQWxCLENBSEssRUFJTCxDQUFDLE1BQU1ELEdBQUcsSUFBSSxFQUFiLENBQUQsRUFBbUIsTUFBTUMsR0FBRyxJQUFJLEVBQWIsQ0FBbkIsQ0FKSyxFQUtMLENBQUMsT0FBT0QsR0FBRyxJQUFJLEVBQWQsQ0FBRCxFQUFvQixPQUFPQyxHQUFHLElBQUksRUFBZCxDQUFwQixDQUxLLEVBTUwsQ0FBQyxRQUFRRCxHQUFHLElBQUksRUFBZixDQUFELEVBQXFCLFFBQVFDLEdBQUcsSUFBSSxFQUFmLENBQXJCLENBTkssQ0FBUDtBQVFEOztJQUVvQkMsVTs7Ozs7Ozs7Ozs7OztnSEFDSEMsTzs7Ozs7Ozs7Ozs7QUFB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QUNNb0MsZ0JBQUFBLEssR0FBUVgsRUFBRSxDQUFDZCxXQUFILENBQWVTLE07QUFDekJpQixnQkFBQUEsTSxHQUFTLEk7QUFDUEMsZ0JBQUFBLE0sR0FBU0MsSUFBSSxDQUFDaEIsR0FBTCxDQUFTQSxHQUFHLElBQUksRUFBaEIsRUFBb0JhLEtBQUssR0FBRyxDQUE1QixDO0FBQ1RJLGdCQUFBQSxNLEdBQVNELElBQUksQ0FBQ2hCLEdBQUwsQ0FBU0MsR0FBRyxJQUFJLEVBQWhCLEVBQW9CWSxLQUFLLEdBQUcsQ0FBNUIsQzs7QUFDZixxQkFBU2pCLENBQVQsR0FBYW1CLE1BQWIsRUFBcUJuQixDQUFDLElBQUlxQixNQUExQixFQUFrQyxFQUFFckIsQ0FBcEMsRUFBdUM7QUFDL0JzQixrQkFBQUEsRUFEK0IsR0FDMUJoQixFQUFFLENBQUNkLFdBQUgsQ0FBZVEsQ0FBZixDQUQwQjs7QUFFckMsc0JBQUlzQixFQUFKLEVBQVE7QUFDTix3QkFBSSxDQUFDSixNQUFELElBQVdJLEVBQUUsQ0FBQ0MsU0FBSCxDQUFhTCxNQUFiLElBQXVCLENBQXRDLEVBQXlDO0FBQ3ZDQSxzQkFBQUEsTUFBTSxHQUFHSSxFQUFUO0FBQ0Q7QUFDRjtBQUNGOztrREFFTSwwQkFBZXRDLE1BQWYsRUFBdUJrQyxNQUF2QixDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7RUFyTjZCTSxrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBMb25nIGZyb20gJ2xvbmcnXG5pbXBvcnQgVmlydHVhbE9mZnNldCwgeyBmcm9tQnl0ZXMgfSBmcm9tICcuL3ZpcnR1YWxPZmZzZXQnXG5pbXBvcnQgQ2h1bmsgZnJvbSAnLi9jaHVuaydcbmltcG9ydCB7IHVuemlwIH0gZnJvbSAnQGdtb2QvYmd6Zi1maWxlaGFuZGxlJ1xuaW1wb3J0IHsgbG9uZ1RvTnVtYmVyLCBvcHRpbWl6ZUNodW5rcywgY2hlY2tBYm9ydFNpZ25hbCB9IGZyb20gJy4vdXRpbCdcbmltcG9ydCBJbmRleEZpbGUsIHsgT3B0aW9ucyB9IGZyb20gJy4vaW5kZXhGaWxlJ1xuXG5jb25zdCBUQklfTUFHSUMgPSAyMTU3ODMyNCAvLyBUQklcXDFcbmNvbnN0IFRBRF9MSURYX1NISUZUID0gMTRcblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIGxpc3Qgb2YgYmlucyB0aGF0IG1heSBvdmVybGFwIHdpdGggcmVnaW9uIFtiZWcsZW5kKSAoemVyby1iYXNlZCBoYWxmLW9wZW4pXG4gKiBAcmV0dXJucyB7QXJyYXlbbnVtYmVyXX1cbiAqL1xuZnVuY3Rpb24gcmVnMmJpbnMoYmVnOiBudW1iZXIsIGVuZDogbnVtYmVyKSB7XG4gIGJlZyArPSAxIC8vIDwgY29udmVydCB0byAxLWJhc2VkIGNsb3NlZFxuICBlbmQgLT0gMVxuICByZXR1cm4gW1xuICAgIFswLCAwXSxcbiAgICBbMSArIChiZWcgPj4gMjYpLCAxICsgKGVuZCA+PiAyNildLFxuICAgIFs5ICsgKGJlZyA+PiAyMyksIDkgKyAoZW5kID4+IDIzKV0sXG4gICAgWzczICsgKGJlZyA+PiAyMCksIDczICsgKGVuZCA+PiAyMCldLFxuICAgIFs1ODUgKyAoYmVnID4+IDE3KSwgNTg1ICsgKGVuZCA+PiAxNyldLFxuICAgIFs0NjgxICsgKGJlZyA+PiAxNCksIDQ2ODEgKyAoZW5kID4+IDE0KV0sXG4gIF1cbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGFiaXhJbmRleCBleHRlbmRzIEluZGV4RmlsZSB7XG4gIGFzeW5jIGxpbmVDb3VudChyZWZOYW1lOiBzdHJpbmcsIG9wdHM6IE9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGluZGV4RGF0YSA9IGF3YWl0IHRoaXMucGFyc2Uob3B0cylcbiAgICBpZiAoIWluZGV4RGF0YSkgcmV0dXJuIC0xXG4gICAgY29uc3QgcmVmSWQgPSBpbmRleERhdGEucmVmTmFtZVRvSWRbcmVmTmFtZV1cbiAgICBjb25zdCBpZHggPSBpbmRleERhdGEuaW5kaWNlc1tyZWZJZF1cbiAgICBpZiAoIWlkeCkgcmV0dXJuIC0xXG4gICAgY29uc3QgeyBzdGF0cyB9ID0gaW5kZXhEYXRhLmluZGljZXNbcmVmSWRdXG4gICAgaWYgKHN0YXRzKSByZXR1cm4gc3RhdHMubGluZUNvdW50XG4gICAgcmV0dXJuIC0xXG4gIH1cblxuICAvLyBtZW1vaXplXG4gIC8vIGZldGNoIGFuZCBwYXJzZSB0aGUgaW5kZXhcbiAgYXN5bmMgX3BhcnNlKG9wdHM6IE9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGJ5dGVzID0gYXdhaXQgdW56aXAoKGF3YWl0IHRoaXMuZmlsZWhhbmRsZS5yZWFkRmlsZShvcHRzKSkgYXMgQnVmZmVyKVxuICAgIGNoZWNrQWJvcnRTaWduYWwob3B0cy5zaWduYWwpXG5cbiAgICAvLyBjaGVjayBUQkkgbWFnaWMgbnVtYmVyc1xuICAgIGlmIChieXRlcy5yZWFkVUludDMyTEUoMCkgIT09IFRCSV9NQUdJQyAvKiBcIlRCSVxcMVwiICovKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBhIFRCSSBmaWxlJylcbiAgICAgIC8vIFRPRE86IGRvIHdlIG5lZWQgdG8gc3VwcG9ydCBiaWctZW5kaWFuIFRCSSBmaWxlcz9cbiAgICB9XG5cbiAgICAvLyBudW1iZXIgb2YgcmVmZXJlbmNlIHNlcXVlbmNlcyBpbiB0aGUgaW5kZXhcbiAgICBjb25zdCByZWZDb3VudCA9IGJ5dGVzLnJlYWRJbnQzMkxFKDQpXG4gICAgY29uc3QgZm9ybWF0RmxhZ3MgPSBieXRlcy5yZWFkSW50MzJMRSg4KVxuICAgIGNvbnN0IGNvb3JkaW5hdGVUeXBlID1cbiAgICAgIGZvcm1hdEZsYWdzICYgMHgxMDAwMCA/ICd6ZXJvLWJhc2VkLWhhbGYtb3BlbicgOiAnMS1iYXNlZC1jbG9zZWQnXG4gICAgY29uc3QgZm9ybWF0T3B0czogeyBba2V5OiBudW1iZXJdOiBzdHJpbmcgfSA9IHtcbiAgICAgIDA6ICdnZW5lcmljJyxcbiAgICAgIDE6ICdTQU0nLFxuICAgICAgMjogJ1ZDRicsXG4gICAgfVxuICAgIGNvbnN0IGZvcm1hdCA9IGZvcm1hdE9wdHNbZm9ybWF0RmxhZ3MgJiAweGZdXG4gICAgaWYgKCFmb3JtYXQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgVGFiaXggcHJlc2V0IGZvcm1hdCBmbGFncyAke2Zvcm1hdEZsYWdzfWApXG4gICAgY29uc3QgY29sdW1uTnVtYmVycyA9IHtcbiAgICAgIHJlZjogYnl0ZXMucmVhZEludDMyTEUoMTIpLFxuICAgICAgc3RhcnQ6IGJ5dGVzLnJlYWRJbnQzMkxFKDE2KSxcbiAgICAgIGVuZDogYnl0ZXMucmVhZEludDMyTEUoMjApLFxuICAgIH1cbiAgICBjb25zdCBtZXRhVmFsdWUgPSBieXRlcy5yZWFkSW50MzJMRSgyNClcbiAgICBjb25zdCBkZXB0aCA9IDVcbiAgICBjb25zdCBtYXhCaW5OdW1iZXIgPSAoKDEgPDwgKChkZXB0aCArIDEpICogMykpIC0gMSkgLyA3XG4gICAgY29uc3QgbWF4UmVmTGVuZ3RoID0gMiAqKiAoMTQgKyBkZXB0aCAqIDMpXG4gICAgY29uc3QgbWV0YUNoYXIgPSBtZXRhVmFsdWUgPyBTdHJpbmcuZnJvbUNoYXJDb2RlKG1ldGFWYWx1ZSkgOiBudWxsXG4gICAgY29uc3Qgc2tpcExpbmVzID0gYnl0ZXMucmVhZEludDMyTEUoMjgpXG5cbiAgICAvLyByZWFkIHNlcXVlbmNlIGRpY3Rpb25hcnlcbiAgICBjb25zdCBuYW1lU2VjdGlvbkxlbmd0aCA9IGJ5dGVzLnJlYWRJbnQzMkxFKDMyKVxuICAgIGNvbnN0IHsgcmVmTmFtZVRvSWQsIHJlZklkVG9OYW1lIH0gPSB0aGlzLl9wYXJzZU5hbWVCeXRlcyhcbiAgICAgIGJ5dGVzLnNsaWNlKDM2LCAzNiArIG5hbWVTZWN0aW9uTGVuZ3RoKSxcbiAgICApXG5cbiAgICAvLyByZWFkIHRoZSBpbmRleGVzIGZvciBlYWNoIHJlZmVyZW5jZSBzZXF1ZW5jZVxuICAgIGxldCBjdXJyT2Zmc2V0ID0gMzYgKyBuYW1lU2VjdGlvbkxlbmd0aFxuICAgIGxldCBmaXJzdERhdGFMaW5lOiBWaXJ0dWFsT2Zmc2V0IHwgdW5kZWZpbmVkXG4gICAgY29uc3QgaW5kaWNlcyA9IG5ldyBBcnJheShyZWZDb3VudCkuZmlsbCgwKS5tYXAoKCkgPT4ge1xuICAgICAgLy8gdGhlIGJpbm5pbmcgaW5kZXhcbiAgICAgIGNvbnN0IGJpbkNvdW50ID0gYnl0ZXMucmVhZEludDMyTEUoY3Vyck9mZnNldClcbiAgICAgIGN1cnJPZmZzZXQgKz0gNFxuICAgICAgY29uc3QgYmluSW5kZXg6IHsgW2tleTogbnVtYmVyXTogQ2h1bmtbXSB9ID0ge31cbiAgICAgIGxldCBzdGF0c1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBiaW5Db3VudDsgaiArPSAxKSB7XG4gICAgICAgIGNvbnN0IGJpbiA9IGJ5dGVzLnJlYWRVSW50MzJMRShjdXJyT2Zmc2V0KVxuICAgICAgICBjdXJyT2Zmc2V0ICs9IDRcbiAgICAgICAgaWYgKGJpbiA+IG1heEJpbk51bWJlciArIDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAndGFiaXggaW5kZXggY29udGFpbnMgdG9vIG1hbnkgYmlucywgcGxlYXNlIHVzZSBhIENTSSBpbmRleCcsXG4gICAgICAgICAgKVxuICAgICAgICB9IGVsc2UgaWYgKGJpbiA9PT0gbWF4QmluTnVtYmVyICsgMSkge1xuICAgICAgICAgIGNvbnN0IGNodW5rQ291bnQgPSBieXRlcy5yZWFkSW50MzJMRShjdXJyT2Zmc2V0KVxuICAgICAgICAgIGN1cnJPZmZzZXQgKz0gNFxuICAgICAgICAgIGlmIChjaHVua0NvdW50ID09PSAyKSB7XG4gICAgICAgICAgICBzdGF0cyA9IHRoaXMucGFyc2VQc2V1ZG9CaW4oYnl0ZXMsIGN1cnJPZmZzZXQpXG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJPZmZzZXQgKz0gMTYgKiBjaHVua0NvdW50XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgY2h1bmtDb3VudCA9IGJ5dGVzLnJlYWRJbnQzMkxFKGN1cnJPZmZzZXQpXG4gICAgICAgICAgY3Vyck9mZnNldCArPSA0XG4gICAgICAgICAgY29uc3QgY2h1bmtzID0gbmV3IEFycmF5KGNodW5rQ291bnQpXG4gICAgICAgICAgZm9yIChsZXQgayA9IDA7IGsgPCBjaHVua0NvdW50OyBrICs9IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IHUgPSBmcm9tQnl0ZXMoYnl0ZXMsIGN1cnJPZmZzZXQpXG4gICAgICAgICAgICBjb25zdCB2ID0gZnJvbUJ5dGVzKGJ5dGVzLCBjdXJyT2Zmc2V0ICsgOClcbiAgICAgICAgICAgIGN1cnJPZmZzZXQgKz0gMTZcbiAgICAgICAgICAgIGZpcnN0RGF0YUxpbmUgPSB0aGlzLl9maW5kRmlyc3REYXRhKGZpcnN0RGF0YUxpbmUsIHUpXG4gICAgICAgICAgICBjaHVua3Nba10gPSBuZXcgQ2h1bmsodSwgdiwgYmluKVxuICAgICAgICAgIH1cbiAgICAgICAgICBiaW5JbmRleFtiaW5dID0gY2h1bmtzXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gdGhlIGxpbmVhciBpbmRleFxuICAgICAgY29uc3QgbGluZWFyQ291bnQgPSBieXRlcy5yZWFkSW50MzJMRShjdXJyT2Zmc2V0KVxuICAgICAgY3Vyck9mZnNldCArPSA0XG4gICAgICBjb25zdCBsaW5lYXJJbmRleCA9IG5ldyBBcnJheShsaW5lYXJDb3VudClcbiAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgbGluZWFyQ291bnQ7IGsgKz0gMSkge1xuICAgICAgICBsaW5lYXJJbmRleFtrXSA9IGZyb21CeXRlcyhieXRlcywgY3Vyck9mZnNldClcbiAgICAgICAgY3Vyck9mZnNldCArPSA4XG4gICAgICAgIGZpcnN0RGF0YUxpbmUgPSB0aGlzLl9maW5kRmlyc3REYXRhKGZpcnN0RGF0YUxpbmUsIGxpbmVhckluZGV4W2tdKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHsgYmluSW5kZXgsIGxpbmVhckluZGV4LCBzdGF0cyB9XG4gICAgfSlcblxuICAgIHJldHVybiB7XG4gICAgICBpbmRpY2VzLFxuICAgICAgbWV0YUNoYXIsXG4gICAgICBtYXhCaW5OdW1iZXIsXG4gICAgICBtYXhSZWZMZW5ndGgsXG4gICAgICBza2lwTGluZXMsXG4gICAgICBmaXJzdERhdGFMaW5lLFxuICAgICAgY29sdW1uTnVtYmVycyxcbiAgICAgIGNvb3JkaW5hdGVUeXBlLFxuICAgICAgZm9ybWF0LFxuICAgICAgcmVmSWRUb05hbWUsXG4gICAgICByZWZOYW1lVG9JZCxcbiAgICAgIG1heEJsb2NrU2l6ZTogMSA8PCAxNixcbiAgICB9XG4gIH1cblxuICBwYXJzZVBzZXVkb0JpbihieXRlczogQnVmZmVyLCBvZmZzZXQ6IG51bWJlcikge1xuICAgIGNvbnN0IGxpbmVDb3VudCA9IGxvbmdUb051bWJlcihcbiAgICAgIExvbmcuZnJvbUJ5dGVzTEUoXG4gICAgICAgIChieXRlcy5zbGljZShvZmZzZXQgKyAxNiwgb2Zmc2V0ICsgMjQpIGFzIHVua25vd24pIGFzIG51bWJlcltdLFxuICAgICAgICB0cnVlLFxuICAgICAgKSxcbiAgICApXG4gICAgcmV0dXJuIHsgbGluZUNvdW50IH1cbiAgfVxuXG4gIF9wYXJzZU5hbWVCeXRlcyhuYW1lc0J5dGVzOiBCdWZmZXIpIHtcbiAgICBsZXQgY3VyclJlZklkID0gMFxuICAgIGxldCBjdXJyTmFtZVN0YXJ0ID0gMFxuICAgIGNvbnN0IHJlZklkVG9OYW1lOiBzdHJpbmdbXSA9IFtdXG4gICAgY29uc3QgcmVmTmFtZVRvSWQ6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gPSB7fVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmFtZXNCeXRlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgaWYgKCFuYW1lc0J5dGVzW2ldKSB7XG4gICAgICAgIGlmIChjdXJyTmFtZVN0YXJ0IDwgaSkge1xuICAgICAgICAgIGxldCByZWZOYW1lID0gbmFtZXNCeXRlcy50b1N0cmluZygndXRmOCcsIGN1cnJOYW1lU3RhcnQsIGkpXG4gICAgICAgICAgcmVmTmFtZSA9IHRoaXMucmVuYW1lUmVmU2VxKHJlZk5hbWUpXG4gICAgICAgICAgcmVmSWRUb05hbWVbY3VyclJlZklkXSA9IHJlZk5hbWVcbiAgICAgICAgICByZWZOYW1lVG9JZFtyZWZOYW1lXSA9IGN1cnJSZWZJZFxuICAgICAgICB9XG4gICAgICAgIGN1cnJOYW1lU3RhcnQgPSBpICsgMVxuICAgICAgICBjdXJyUmVmSWQgKz0gMVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyByZWZOYW1lVG9JZCwgcmVmSWRUb05hbWUgfVxuICB9XG5cbiAgYXN5bmMgYmxvY2tzRm9yUmFuZ2UoXG4gICAgcmVmTmFtZTogc3RyaW5nLFxuICAgIG1pbjogbnVtYmVyLFxuICAgIG1heDogbnVtYmVyLFxuICAgIG9wdHM6IE9wdGlvbnMgPSB7fSxcbiAgKSB7XG4gICAgaWYgKG1pbiA8IDApIHtcbiAgICAgIG1pbiA9IDBcbiAgICB9XG5cbiAgICBjb25zdCBpbmRleERhdGEgPSBhd2FpdCB0aGlzLnBhcnNlKG9wdHMpXG4gICAgaWYgKCFpbmRleERhdGEpIHtcbiAgICAgIHJldHVybiBbXVxuICAgIH1cbiAgICBjb25zdCByZWZJZCA9IGluZGV4RGF0YS5yZWZOYW1lVG9JZFtyZWZOYW1lXVxuICAgIGNvbnN0IGJhID0gaW5kZXhEYXRhLmluZGljZXNbcmVmSWRdXG4gICAgaWYgKCFiYSkge1xuICAgICAgcmV0dXJuIFtdXG4gICAgfVxuXG4gICAgY29uc3QgbWluT2Zmc2V0ID0gYmEubGluZWFySW5kZXgubGVuZ3RoXG4gICAgICA/IGJhLmxpbmVhckluZGV4W1xuICAgICAgICAgIG1pbiA+PiBUQURfTElEWF9TSElGVCA+PSBiYS5saW5lYXJJbmRleC5sZW5ndGhcbiAgICAgICAgICAgID8gYmEubGluZWFySW5kZXgubGVuZ3RoIC0gMVxuICAgICAgICAgICAgOiBtaW4gPj4gVEFEX0xJRFhfU0hJRlRcbiAgICAgICAgXVxuICAgICAgOiBuZXcgVmlydHVhbE9mZnNldCgwLCAwKVxuICAgIGlmICghbWluT2Zmc2V0KSB7XG4gICAgICBjb25zb2xlLndhcm4oJ3F1ZXJ5aW5nIG91dHNpZGUgb2YgcG9zc2libGUgdGFiaXggcmFuZ2UnKVxuICAgIH1cblxuICAgIC8vIGNvbnN0IHsgbGluZWFySW5kZXgsIGJpbkluZGV4IH0gPSBpbmRleGVzXG5cbiAgICBjb25zdCBvdmVybGFwcGluZ0JpbnMgPSByZWcyYmlucyhtaW4sIG1heCkgLy8gTGlzdCBvZiBiaW4gI3MgdGhhdCBvdmVybGFwIG1pbiwgbWF4XG4gICAgY29uc3QgY2h1bmtzOiBDaHVua1tdID0gW11cblxuICAgIC8vIEZpbmQgY2h1bmtzIGluIG92ZXJsYXBwaW5nIGJpbnMuICBMZWFmIGJpbnMgKDwgNDY4MSkgYXJlIG5vdCBwcnVuZWRcbiAgICBmb3IgKGNvbnN0IFtzdGFydCwgZW5kXSBvZiBvdmVybGFwcGluZ0JpbnMpIHtcbiAgICAgIGZvciAobGV0IGJpbiA9IHN0YXJ0OyBiaW4gPD0gZW5kOyBiaW4rKykge1xuICAgICAgICBpZiAoYmEuYmluSW5kZXhbYmluXSkge1xuICAgICAgICAgIGNvbnN0IGJpbkNodW5rcyA9IGJhLmJpbkluZGV4W2Jpbl1cbiAgICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGJpbkNodW5rcy5sZW5ndGg7ICsrYykge1xuICAgICAgICAgICAgY2h1bmtzLnB1c2gobmV3IENodW5rKGJpbkNodW5rc1tjXS5taW52LCBiaW5DaHVua3NbY10ubWF4diwgYmluKSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBVc2UgdGhlIGxpbmVhciBpbmRleCB0byBmaW5kIG1pbmltdW0gZmlsZSBwb3NpdGlvbiBvZiBjaHVua3MgdGhhdCBjb3VsZCBjb250YWluIGFsaWdubWVudHMgaW4gdGhlIHJlZ2lvblxuICAgIGNvbnN0IG5pbnR2ID0gYmEubGluZWFySW5kZXgubGVuZ3RoXG4gICAgbGV0IGxvd2VzdCA9IG51bGxcbiAgICBjb25zdCBtaW5MaW4gPSBNYXRoLm1pbihtaW4gPj4gMTQsIG5pbnR2IC0gMSlcbiAgICBjb25zdCBtYXhMaW4gPSBNYXRoLm1pbihtYXggPj4gMTQsIG5pbnR2IC0gMSlcbiAgICBmb3IgKGxldCBpID0gbWluTGluOyBpIDw9IG1heExpbjsgKytpKSB7XG4gICAgICBjb25zdCB2cCA9IGJhLmxpbmVhckluZGV4W2ldXG4gICAgICBpZiAodnApIHtcbiAgICAgICAgaWYgKCFsb3dlc3QgfHwgdnAuY29tcGFyZVRvKGxvd2VzdCkgPCAwKSB7XG4gICAgICAgICAgbG93ZXN0ID0gdnBcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvcHRpbWl6ZUNodW5rcyhjaHVua3MsIGxvd2VzdClcbiAgfVxufVxuIl19