1 | 'use strict';
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.convertFromVMDK = exports.ReadableRawVHDStream = exports.VHDFile = undefined;
|
7 |
|
8 | var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
|
9 |
|
10 | var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
|
11 |
|
12 | var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
|
13 |
|
14 | var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
|
15 |
|
16 | var _inherits2 = require('babel-runtime/helpers/inherits');
|
17 |
|
18 | var _inherits3 = _interopRequireDefault(_inherits2);
|
19 |
|
20 | var _regenerator = require('babel-runtime/regenerator');
|
21 |
|
22 | var _regenerator2 = _interopRequireDefault(_regenerator);
|
23 |
|
24 | var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
|
25 |
|
26 | var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
|
27 |
|
28 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
29 |
|
30 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
31 |
|
32 | var _createClass2 = require('babel-runtime/helpers/createClass');
|
33 |
|
34 | var _createClass3 = _interopRequireDefault(_createClass2);
|
35 |
|
36 | var convertFromVMDK = exports.convertFromVMDK = function () {
|
37 | var _ref6 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee6(vmdkReadStream) {
|
38 | var parser, header;
|
39 | return _regenerator2.default.wrap(function _callee6$(_context6) {
|
40 | while (1) {
|
41 | switch (_context6.prev = _context6.next) {
|
42 | case 0:
|
43 | parser = new _vmdkRead.VMDKDirectParser(vmdkReadStream);
|
44 | _context6.next = 3;
|
45 | return parser.readHeader();
|
46 |
|
47 | case 3:
|
48 | header = _context6.sent;
|
49 | return _context6.abrupt('return', new ReadableRawVHDStream(header.capacitySectors * sectorSize, parser));
|
50 |
|
51 | case 5:
|
52 | case 'end':
|
53 | return _context6.stop();
|
54 | }
|
55 | }
|
56 | }, _callee6, this);
|
57 | }));
|
58 |
|
59 | return function convertFromVMDK(_x9) {
|
60 | return _ref6.apply(this, arguments);
|
61 | };
|
62 | }();
|
63 |
|
64 | exports.computeChecksum = computeChecksum;
|
65 | exports.computeGeometryForSize = computeGeometryForSize;
|
66 | exports.createFooter = createFooter;
|
67 | exports.createDynamicDiskHeader = createDynamicDiskHeader;
|
68 | exports.createEmptyTable = createEmptyTable;
|
69 |
|
70 | var _fsPromise = require('fs-promise');
|
71 |
|
72 | var _stream = require('stream');
|
73 |
|
74 | var _stream2 = _interopRequireDefault(_stream);
|
75 |
|
76 | var _vmdkRead = require('./vmdk-read');
|
77 |
|
78 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
79 |
|
80 | var footerCookie = 'conectix';
|
81 | var creatorApp = 'xo ';
|
82 |
|
83 | var osString = 'Wi2k';
|
84 | var headerCookie = 'cxsparse';
|
85 | var fixedHardDiskType = 2;
|
86 | var dynamicHardDiskType = 3;
|
87 |
|
88 | var sectorSize = 512;
|
89 |
|
90 | function computeChecksum(buffer) {
|
91 | var sum = 0;
|
92 | for (var i = 0; i < buffer.length; i++) {
|
93 | sum += buffer[i];
|
94 | }
|
95 |
|
96 | return ~sum >>> 0;
|
97 | }
|
98 |
|
99 | var Block = function () {
|
100 | function Block(blockSize) {
|
101 | (0, _classCallCheck3.default)(this, Block);
|
102 |
|
103 | var bitmapSize = blockSize / sectorSize / 8;
|
104 | var bufferSize = Math.ceil((blockSize + bitmapSize) / sectorSize) * sectorSize;
|
105 | this.buffer = new Buffer(bufferSize);
|
106 | this.buffer.fill(0);
|
107 | this.bitmapBuffer = this.buffer.slice(0, bitmapSize);
|
108 | this.dataBuffer = this.buffer.slice(bitmapSize);
|
109 | this.bitmapBuffer.fill(0xff);
|
110 | }
|
111 |
|
112 | (0, _createClass3.default)(Block, [{
|
113 | key: 'writeData',
|
114 | value: function writeData(buffer) {
|
115 | var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
|
116 |
|
117 | buffer.copy(this.dataBuffer, offset);
|
118 | }
|
119 | }, {
|
120 | key: 'writeOnFile',
|
121 | value: function () {
|
122 | var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(file) {
|
123 | return _regenerator2.default.wrap(function _callee$(_context) {
|
124 | while (1) {
|
125 | switch (_context.prev = _context.next) {
|
126 | case 0:
|
127 | _context.next = 2;
|
128 | return (0, _fsPromise.write)(file, this.buffer, 0, this.buffer.length);
|
129 |
|
130 | case 2:
|
131 | case 'end':
|
132 | return _context.stop();
|
133 | }
|
134 | }
|
135 | }, _callee, this);
|
136 | }));
|
137 |
|
138 | function writeOnFile(_x2) {
|
139 | return _ref.apply(this, arguments);
|
140 | }
|
141 |
|
142 | return writeOnFile;
|
143 | }()
|
144 | }]);
|
145 | return Block;
|
146 | }();
|
147 |
|
148 | var SparseExtent = function () {
|
149 | function SparseExtent(dataSize, blockSize, startOffset) {
|
150 | (0, _classCallCheck3.default)(this, SparseExtent);
|
151 |
|
152 | this.table = createEmptyTable(dataSize, blockSize);
|
153 | this.blockSize = blockSize;
|
154 | this.startOffset = (startOffset + this.table.buffer.length) / sectorSize;
|
155 | }
|
156 |
|
157 | (0, _createClass3.default)(SparseExtent, [{
|
158 | key: '_writeBlock',
|
159 | value: function _writeBlock(blockBuffer, tableIndex, offset) {
|
160 | if (blockBuffer.length + offset > this.blockSize) {
|
161 | throw new Error('invalid block geometry');
|
162 | }
|
163 | var entry = this.table.entries[tableIndex];
|
164 | if (entry === undefined) {
|
165 | entry = new Block(this.blockSize);
|
166 | this.table.entries[tableIndex] = entry;
|
167 | }
|
168 | entry.writeData(blockBuffer, offset);
|
169 | }
|
170 | }, {
|
171 | key: 'writeBuffer',
|
172 | value: function writeBuffer(buffer) {
|
173 | var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
|
174 |
|
175 | var startBlock = Math.floor(offset / this.blockSize);
|
176 | var endBlock = Math.ceil((offset + buffer.length) / this.blockSize);
|
177 | for (var i = startBlock; i < endBlock; i++) {
|
178 | var blockDelta = offset - i * this.blockSize;
|
179 | var blockBuffer = void 0,
|
180 | blockOffset = void 0;
|
181 | if (blockDelta > 0) {
|
182 | blockBuffer = buffer.slice(0, (i + 1) * this.blockSize - offset);
|
183 | blockOffset = blockDelta;
|
184 | } else {
|
185 | blockBuffer = buffer.slice(-blockDelta, (i + 1) * this.blockSize - offset);
|
186 | blockOffset = 0;
|
187 | }
|
188 | this._writeBlock(blockBuffer, i, blockOffset);
|
189 | }
|
190 | }
|
191 | }, {
|
192 | key: 'writeOnFile',
|
193 | value: function () {
|
194 | var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(file) {
|
195 | var currentOffset, i, block, _i, _block;
|
196 |
|
197 | return _regenerator2.default.wrap(function _callee2$(_context2) {
|
198 | while (1) {
|
199 | switch (_context2.prev = _context2.next) {
|
200 | case 0:
|
201 | currentOffset = this.startOffset;
|
202 |
|
203 | for (i = 0; i < this.table.entryCount; i++) {
|
204 | block = this.table.entries[i];
|
205 |
|
206 | if (block !== undefined) {
|
207 | this.table.buffer.writeUInt32BE(currentOffset, i * 4);
|
208 | currentOffset += block.buffer.length / sectorSize;
|
209 | }
|
210 | }
|
211 | _context2.next = 4;
|
212 | return (0, _fsPromise.write)(file, this.table.buffer, 0, this.table.buffer.length);
|
213 |
|
214 | case 4:
|
215 | _i = 0;
|
216 |
|
217 | case 5:
|
218 | if (!(_i < this.table.entryCount)) {
|
219 | _context2.next = 13;
|
220 | break;
|
221 | }
|
222 |
|
223 | _block = this.table.entries[_i];
|
224 |
|
225 | if (!(_block !== undefined)) {
|
226 | _context2.next = 10;
|
227 | break;
|
228 | }
|
229 |
|
230 | _context2.next = 10;
|
231 | return _block.writeOnFile(file);
|
232 |
|
233 | case 10:
|
234 | _i++;
|
235 | _context2.next = 5;
|
236 | break;
|
237 |
|
238 | case 13:
|
239 | case 'end':
|
240 | return _context2.stop();
|
241 | }
|
242 | }
|
243 | }, _callee2, this);
|
244 | }));
|
245 |
|
246 | function writeOnFile(_x4) {
|
247 | return _ref2.apply(this, arguments);
|
248 | }
|
249 |
|
250 | return writeOnFile;
|
251 | }()
|
252 | }, {
|
253 | key: 'entryCount',
|
254 | get: function get() {
|
255 | return this.table.entryCount;
|
256 | }
|
257 | }]);
|
258 | return SparseExtent;
|
259 | }();
|
260 |
|
261 | var VHDFile = exports.VHDFile = function () {
|
262 | function VHDFile(virtualSize, timestamp) {
|
263 | (0, _classCallCheck3.default)(this, VHDFile);
|
264 |
|
265 | this.geomtry = computeGeometryForSize(virtualSize);
|
266 | this.timestamp = timestamp;
|
267 | this.blockSize = 0x00200000;
|
268 | this.sparseFile = new SparseExtent(this.geomtry.actualSize, this.blockSize, sectorSize * 3);
|
269 | }
|
270 |
|
271 | (0, _createClass3.default)(VHDFile, [{
|
272 | key: 'writeBuffer',
|
273 | value: function writeBuffer(buffer) {
|
274 | var offset = arguments.length <= 1 || arguments[1] === undefined ? 0 : arguments[1];
|
275 |
|
276 | this.sparseFile.writeBuffer(buffer, offset);
|
277 | }
|
278 | }, {
|
279 | key: 'writeFile',
|
280 | value: function () {
|
281 | var _ref3 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(fileName) {
|
282 | var fileFooter, diskHeader, file;
|
283 | return _regenerator2.default.wrap(function _callee3$(_context3) {
|
284 | while (1) {
|
285 | switch (_context3.prev = _context3.next) {
|
286 | case 0:
|
287 | fileFooter = createFooter(this.geomtry.actualSize, this.timestamp, this.geomtry, dynamicHardDiskType, 512, 0);
|
288 | diskHeader = createDynamicDiskHeader(this.sparseFile.entryCount, this.blockSize);
|
289 | _context3.next = 4;
|
290 | return (0, _fsPromise.open)(fileName, 'w');
|
291 |
|
292 | case 4:
|
293 | file = _context3.sent;
|
294 | _context3.next = 7;
|
295 | return (0, _fsPromise.write)(file, fileFooter, 0, fileFooter.length);
|
296 |
|
297 | case 7:
|
298 | _context3.next = 9;
|
299 | return (0, _fsPromise.write)(file, diskHeader, 0, diskHeader.length);
|
300 |
|
301 | case 9:
|
302 | _context3.next = 11;
|
303 | return this.sparseFile.writeOnFile(file);
|
304 |
|
305 | case 11:
|
306 | _context3.next = 13;
|
307 | return (0, _fsPromise.write)(file, fileFooter, 0, fileFooter.length);
|
308 |
|
309 | case 13:
|
310 | case 'end':
|
311 | return _context3.stop();
|
312 | }
|
313 | }
|
314 | }, _callee3, this);
|
315 | }));
|
316 |
|
317 | function writeFile(_x6) {
|
318 | return _ref3.apply(this, arguments);
|
319 | }
|
320 |
|
321 | return writeFile;
|
322 | }()
|
323 | }]);
|
324 | return VHDFile;
|
325 | }();
|
326 |
|
327 | function computeGeometryForSize(size) {
|
328 | var totalSectors = Math.ceil(size / 512);
|
329 | var sectorsPerTrack = void 0;
|
330 | var heads = void 0;
|
331 | var cylinderTimesHeads = void 0;
|
332 | if (totalSectors > 65535 * 16 * 255) {
|
333 | throw Error('disk is too big');
|
334 | }
|
335 |
|
336 | if (totalSectors >= 65535 * 16 * 63) {
|
337 | sectorsPerTrack = 255;
|
338 | heads = 16;
|
339 | cylinderTimesHeads = totalSectors / sectorsPerTrack;
|
340 | } else {
|
341 | sectorsPerTrack = 17;
|
342 | cylinderTimesHeads = totalSectors / sectorsPerTrack;
|
343 | heads = Math.floor((cylinderTimesHeads + 1023) / 1024);
|
344 | if (heads < 4) {
|
345 | heads = 4;
|
346 | }
|
347 | if (cylinderTimesHeads >= heads * 1024 || heads > 16) {
|
348 | sectorsPerTrack = 31;
|
349 | heads = 16;
|
350 | cylinderTimesHeads = totalSectors / sectorsPerTrack;
|
351 | }
|
352 | if (cylinderTimesHeads >= heads * 1024) {
|
353 | sectorsPerTrack = 63;
|
354 | heads = 16;
|
355 | cylinderTimesHeads = totalSectors / sectorsPerTrack;
|
356 | }
|
357 | }
|
358 | var cylinders = Math.floor(cylinderTimesHeads / heads);
|
359 | var actualSize = cylinders * heads * sectorsPerTrack * sectorSize;
|
360 | return { cylinders: cylinders, heads: heads, sectorsPerTrack: sectorsPerTrack, actualSize: actualSize };
|
361 | }
|
362 |
|
363 | function createFooter(size, timestamp, geometry, diskType) {
|
364 | var dataOffsetLow = arguments.length <= 4 || arguments[4] === undefined ? 0xFFFFFFFF : arguments[4];
|
365 | var dataOffsetHigh = arguments.length <= 5 || arguments[5] === undefined ? 0xFFFFFFFF : arguments[5];
|
366 |
|
367 | var footer = new Buffer(512);
|
368 | footer.fill(0);
|
369 | new Buffer(footerCookie, 'ascii').copy(footer);
|
370 | footer.writeUInt32BE(2, 8);
|
371 | footer.writeUInt32BE(0x00010000, 12);
|
372 | footer.writeUInt32BE(dataOffsetHigh, 16);
|
373 | footer.writeUInt32BE(dataOffsetLow, 20);
|
374 | footer.writeUInt32BE(timestamp, 24);
|
375 | new Buffer(creatorApp, 'ascii').copy(footer, 28);
|
376 | new Buffer(osString, 'ascii').copy(footer, 36);
|
377 |
|
378 | var sizeHigh = Math.floor(size / Math.pow(2, 32)) % Math.pow(2, 32);
|
379 | var sizeLow = size % Math.pow(2, 32);
|
380 | footer.writeUInt32BE(sizeHigh, 40);
|
381 | footer.writeUInt32BE(sizeLow, 44);
|
382 | footer.writeUInt32BE(sizeHigh, 48);
|
383 | footer.writeUInt32BE(sizeLow, 52);
|
384 | footer.writeUInt16BE(geometry['cylinders'], 56);
|
385 | footer.writeUInt8(geometry['heads'], 58);
|
386 | footer.writeUInt8(geometry['sectorsPerTrack'], 59);
|
387 | footer.writeUInt32BE(diskType, 60);
|
388 | var checksum = computeChecksum(footer);
|
389 | footer.writeUInt32BE(checksum, 64);
|
390 | return footer;
|
391 | }
|
392 |
|
393 | function createDynamicDiskHeader(tableEntries, blockSize) {
|
394 | var header = new Buffer(1024);
|
395 | header.fill(0);
|
396 | new Buffer(headerCookie, 'ascii').copy(header);
|
397 |
|
398 | header.writeUInt32BE(0xFFFFFFFF, 8);
|
399 | header.writeUInt32BE(0xFFFFFFFF, 12);
|
400 |
|
401 | header.writeUInt32BE(0, 16);
|
402 | header.writeUInt32BE(sectorSize * 3, 20);
|
403 | header.writeUInt32BE(0x00010000, 24);
|
404 | header.writeUInt32BE(tableEntries, 28);
|
405 | header.writeUInt32BE(blockSize, 32);
|
406 | var checksum = computeChecksum(header);
|
407 | header.writeUInt32BE(checksum, 36);
|
408 | return header;
|
409 | }
|
410 |
|
411 | function createEmptyTable(dataSize, blockSize) {
|
412 | var blockCount = Math.ceil(dataSize / blockSize);
|
413 | var tableSizeSectors = Math.ceil(blockCount * 4 / sectorSize);
|
414 | var buffer = new Buffer(tableSizeSectors * sectorSize);
|
415 | buffer.fill(0xff);
|
416 | return { entryCount: blockCount, buffer: buffer, entries: [] };
|
417 | }
|
418 |
|
419 | var ReadableRawVHDStream = exports.ReadableRawVHDStream = function (_stream$Readable) {
|
420 | (0, _inherits3.default)(ReadableRawVHDStream, _stream$Readable);
|
421 |
|
422 | function ReadableRawVHDStream(size, vmdkParser) {
|
423 | (0, _classCallCheck3.default)(this, ReadableRawVHDStream);
|
424 |
|
425 | var _this = (0, _possibleConstructorReturn3.default)(this, (0, _getPrototypeOf2.default)(ReadableRawVHDStream).call(this));
|
426 |
|
427 | _this.size = size;
|
428 | var geometry = computeGeometryForSize(size);
|
429 | _this.footer = createFooter(size, Math.floor(Date.now() / 1000), geometry, fixedHardDiskType);
|
430 | _this.position = 0;
|
431 | _this.vmdkParser = vmdkParser;
|
432 | _this.done = false;
|
433 | _this.busy = false;
|
434 | _this.currentFile = [];
|
435 | return _this;
|
436 | }
|
437 |
|
438 | (0, _createClass3.default)(ReadableRawVHDStream, [{
|
439 | key: 'filePadding',
|
440 | value: function filePadding(paddingLength) {
|
441 | var _this2 = this;
|
442 |
|
443 | if (paddingLength !== 0) {
|
444 | (function () {
|
445 | var chunkSize = 1024 * 1024;
|
446 | var chunkCount = Math.floor(paddingLength / chunkSize);
|
447 | for (var i = 0; i < chunkCount; i++) {
|
448 | _this2.currentFile.push(function () {
|
449 | var paddingBuffer = new Buffer(chunkSize);
|
450 | paddingBuffer.fill(0);
|
451 | return paddingBuffer;
|
452 | });
|
453 | }
|
454 | _this2.currentFile.push(function () {
|
455 | var paddingBuffer = new Buffer(paddingLength % chunkSize);
|
456 | paddingBuffer.fill(0);
|
457 | return paddingBuffer;
|
458 | });
|
459 | })();
|
460 | }
|
461 | }
|
462 | }, {
|
463 | key: 'pushNextBlock',
|
464 | value: function () {
|
465 | var _ref4 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4() {
|
466 | var _this3 = this;
|
467 |
|
468 | var next, paddingLength;
|
469 | return _regenerator2.default.wrap(function _callee4$(_context4) {
|
470 | while (1) {
|
471 | switch (_context4.prev = _context4.next) {
|
472 | case 0:
|
473 | _context4.next = 2;
|
474 | return this.vmdkParser.next();
|
475 |
|
476 | case 2:
|
477 | next = _context4.sent;
|
478 |
|
479 | if (next === null) {
|
480 | paddingLength = this.size - this.position;
|
481 |
|
482 | this.filePadding(paddingLength);
|
483 | this.currentFile.push(function () {
|
484 | return _this3.footer;
|
485 | });
|
486 | this.currentFile.push(function () {
|
487 | _this3.done = true;
|
488 | return null;
|
489 | });
|
490 | } else {
|
491 | (function () {
|
492 | var offset = next.lbaBytes;
|
493 | var buffer = next.grain;
|
494 | var paddingLength = offset - _this3.position;
|
495 | if (paddingLength < 0) {
|
496 | process.nextTick(function () {
|
497 | return _this3.emit('error', 'This VMDK file does not have its blocks in the correct order');
|
498 | });
|
499 | }
|
500 | _this3.filePadding(paddingLength);
|
501 | _this3.currentFile.push(function () {
|
502 | return buffer;
|
503 | });
|
504 | _this3.position = offset + buffer.length;
|
505 | })();
|
506 | }
|
507 | return _context4.abrupt('return', this.pushFileUntilFull());
|
508 |
|
509 | case 5:
|
510 | case 'end':
|
511 | return _context4.stop();
|
512 | }
|
513 | }
|
514 | }, _callee4, this);
|
515 | }));
|
516 |
|
517 | function pushNextBlock() {
|
518 | return _ref4.apply(this, arguments);
|
519 | }
|
520 |
|
521 | return pushNextBlock;
|
522 | }()
|
523 |
|
524 |
|
525 |
|
526 | }, {
|
527 | key: 'pushFileUntilFull',
|
528 | value: function pushFileUntilFull() {
|
529 | while (true) {
|
530 | if (this.currentFile.length === 0) {
|
531 | break;
|
532 | }
|
533 | var result = this.push(this.currentFile.shift()());
|
534 | if (!result) {
|
535 | break;
|
536 | }
|
537 | }
|
538 | return this.currentFile.length === 0;
|
539 | }
|
540 | }, {
|
541 | key: 'pushNextUntilFull',
|
542 | value: function () {
|
543 | var _ref5 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5() {
|
544 | return _regenerator2.default.wrap(function _callee5$(_context5) {
|
545 | while (1) {
|
546 | switch (_context5.prev = _context5.next) {
|
547 | case 0:
|
548 | _context5.t0 = !this.done;
|
549 |
|
550 | if (!_context5.t0) {
|
551 | _context5.next = 5;
|
552 | break;
|
553 | }
|
554 |
|
555 | _context5.next = 4;
|
556 | return this.pushNextBlock();
|
557 |
|
558 | case 4:
|
559 | _context5.t0 = _context5.sent;
|
560 |
|
561 | case 5:
|
562 | if (!_context5.t0) {
|
563 | _context5.next = 8;
|
564 | break;
|
565 | }
|
566 |
|
567 | _context5.next = 0;
|
568 | break;
|
569 |
|
570 | case 8:
|
571 | case 'end':
|
572 | return _context5.stop();
|
573 | }
|
574 | }
|
575 | }, _callee5, this);
|
576 | }));
|
577 |
|
578 | function pushNextUntilFull() {
|
579 | return _ref5.apply(this, arguments);
|
580 | }
|
581 |
|
582 | return pushNextUntilFull;
|
583 | }()
|
584 | }, {
|
585 | key: '_read',
|
586 | value: function _read() {
|
587 | var _this4 = this;
|
588 |
|
589 | if (this.busy || this.done) {
|
590 | return;
|
591 | }
|
592 | if (this.pushFileUntilFull()) {
|
593 | this.busy = true;
|
594 | this.pushNextUntilFull().then(function () {
|
595 | _this4.busy = false;
|
596 | }).catch(function (error) {
|
597 | process.nextTick(function () {
|
598 | return _this4.emit('error', error);
|
599 | });
|
600 | });
|
601 | }
|
602 | }
|
603 | }]);
|
604 | return ReadableRawVHDStream;
|
605 | }(_stream2.default.Readable);
|
606 |
|
\ | No newline at end of file |