diff --git a/dist/dash.all.debug.js b/dist/dash.all.debug.js index 9791834f79..86551cd2f8 100644 --- a/dist/dash.all.debug.js +++ b/dist/dash.all.debug.js @@ -1,4 +1,4 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + throw new Error('Invalid string. Length must be a multiple of 4') } - ISOBox.prototype._boxProcessors[type] = parser; -}; -ISOBoxer.createFile = function() { - return new ISOFile(); -}; + // Trim off extra bytes after placeholder bytes are found + // See: https://github.com/beatgammit/base64-js/issues/42 + var validLen = b64.indexOf('=') + if (validLen === -1) validLen = len -// See ISOBoxer.append() for 'pos' parameter syntax -ISOBoxer.createBox = function(type, parent, pos) { - var newBox = ISOBox.create(type); - if (parent) { - parent.append(newBox, pos); + var placeHoldersLen = validLen === len + ? 0 + : 4 - (validLen % 4) + + return [validLen, placeHoldersLen] +} + +// base64 is 4/3 + up to two characters of the original data +function byteLength (b64) { + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function _byteLength (b64, validLen, placeHoldersLen) { + return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen +} + +function toByteArray (b64) { + var tmp + var lens = getLens(b64) + var validLen = lens[0] + var placeHoldersLen = lens[1] + + var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)) + + var curByte = 0 + + // if there are placeholders, only get up to the last complete 4 chars + var len = placeHoldersLen > 0 + ? validLen - 4 + : validLen + + for (var i = 0; i < len; i += 4) { + tmp = + (revLookup[b64.charCodeAt(i)] << 18) | + (revLookup[b64.charCodeAt(i + 1)] << 12) | + (revLookup[b64.charCodeAt(i + 2)] << 6) | + revLookup[b64.charCodeAt(i + 3)] + arr[curByte++] = (tmp >> 16) & 0xFF + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF } - return newBox; -}; -// See ISOBoxer.append() for 'pos' parameter syntax -ISOBoxer.createFullBox = function(type, parent, pos) { - var newBox = ISOBoxer.createBox(type, parent, pos); - newBox.version = 0; - newBox.flags = 0; - return newBox; -}; + if (placeHoldersLen === 2) { + tmp = + (revLookup[b64.charCodeAt(i)] << 2) | + (revLookup[b64.charCodeAt(i + 1)] >> 4) + arr[curByte++] = tmp & 0xFF + } -ISOBoxer.Utils = {}; -ISOBoxer.Utils.dataViewToString = function(dataView, encoding) { - var impliedEncoding = encoding || 'utf-8'; - if (typeof TextDecoder !== 'undefined') { - return new TextDecoder(impliedEncoding).decode(dataView); + if (placeHoldersLen === 1) { + tmp = + (revLookup[b64.charCodeAt(i)] << 10) | + (revLookup[b64.charCodeAt(i + 1)] << 4) | + (revLookup[b64.charCodeAt(i + 2)] >> 2) + arr[curByte++] = (tmp >> 8) & 0xFF + arr[curByte++] = tmp & 0xFF } - var a = []; - var i = 0; - if (impliedEncoding === 'utf-8') { - /* The following algorithm is essentially a rewrite of the UTF8.decode at - http://bannister.us/weblog/2007/simple-base64-encodedecode-javascript/ - */ + return arr +} - while (i < dataView.byteLength) { - var c = dataView.getUint8(i++); - if (c < 0x80) { - // 1-byte character (7 bits) - } else if (c < 0xe0) { - // 2-byte character (11 bits) - c = (c & 0x1f) << 6; - c |= (dataView.getUint8(i++) & 0x3f); - } else if (c < 0xf0) { - // 3-byte character (16 bits) - c = (c & 0xf) << 12; - c |= (dataView.getUint8(i++) & 0x3f) << 6; - c |= (dataView.getUint8(i++) & 0x3f); - } else { - // 4-byte character (21 bits) - c = (c & 0x7) << 18; - c |= (dataView.getUint8(i++) & 0x3f) << 12; - c |= (dataView.getUint8(i++) & 0x3f) << 6; - c |= (dataView.getUint8(i++) & 0x3f); - } - a.push(String.fromCharCode(c)); - } - } else { // Just map byte-by-byte (probably wrong) - while (i < dataView.byteLength) { - a.push(String.fromCharCode(dataView.getUint8(i++))); - } +function tripletToBase64 (num) { + return lookup[num >> 18 & 0x3F] + + lookup[num >> 12 & 0x3F] + + lookup[num >> 6 & 0x3F] + + lookup[num & 0x3F] +} + +function encodeChunk (uint8, start, end) { + var tmp + var output = [] + for (var i = start; i < end; i += 3) { + tmp = + ((uint8[i] << 16) & 0xFF0000) + + ((uint8[i + 1] << 8) & 0xFF00) + + (uint8[i + 2] & 0xFF) + output.push(tripletToBase64(tmp)) } - return a.join(''); -}; + return output.join('') +} -ISOBoxer.Utils.utf8ToByteArray = function(string) { - // Only UTF-8 encoding is supported by TextEncoder - var u, i; - if (typeof TextEncoder !== 'undefined') { - u = new TextEncoder().encode(string); - } else { - u = []; - for (i = 0; i < string.length; ++i) { - var c = string.charCodeAt(i); - if (c < 0x80) { - u.push(c); - } else if (c < 0x800) { - u.push(0xC0 | (c >> 6)); - u.push(0x80 | (63 & c)); - } else if (c < 0x10000) { - u.push(0xE0 | (c >> 12)); - u.push(0x80 | (63 & (c >> 6))); - u.push(0x80 | (63 & c)); - } else { - u.push(0xF0 | (c >> 18)); - u.push(0x80 | (63 & (c >> 12))); - u.push(0x80 | (63 & (c >> 6))); - u.push(0x80 | (63 & c)); - } - } +function fromByteArray (uint8) { + var tmp + var len = uint8.length + var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes + var parts = [] + var maxChunkLength = 16383 // must be multiple of 3 + + // go through the array every three bytes, we'll deal with trailing stuff later + for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) { + parts.push(encodeChunk( + uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength) + )) } - return u; -}; -// Method to append a box in the list of child boxes -// The 'pos' parameter can be either: -// - (number) a position index at which to insert the new box -// - (string) the type of the box after which to insert the new box -// - (object) the box after which to insert the new box -ISOBoxer.Utils.appendBox = function(parent, box, pos) { - box._offset = parent._cursor.offset; - box._root = (parent._root ? parent._root : parent); - box._raw = parent._raw; - box._parent = parent; + // pad the end with zeros, but make sure to not forget the extra bytes + if (extraBytes === 1) { + tmp = uint8[len - 1] + parts.push( + lookup[tmp >> 2] + + lookup[(tmp << 4) & 0x3F] + + '==' + ) + } else if (extraBytes === 2) { + tmp = (uint8[len - 2] << 8) + uint8[len - 1] + parts.push( + lookup[tmp >> 10] + + lookup[(tmp >> 4) & 0x3F] + + lookup[(tmp << 2) & 0x3F] + + '=' + ) + } - if (pos === -1) { - // The new box is a sub-box of the parent but not added in boxes array, - // for example when the new box is set as an entry (see dref and stsd for example) - return; + return parts.join('') +} + +},{}],7:[function(_dereq_,module,exports){ + +},{}],8:[function(_dereq_,module,exports){ +/*! + * The buffer module from node.js, for the browser. + * + * @author Feross Aboukhadijeh + * @license MIT + */ +/* eslint-disable no-proto */ + +'use strict' + +var base64 = _dereq_(6) +var ieee754 = _dereq_(12) + +exports.Buffer = Buffer +exports.SlowBuffer = SlowBuffer +exports.INSPECT_MAX_BYTES = 50 + +var K_MAX_LENGTH = 0x7fffffff +exports.kMaxLength = K_MAX_LENGTH + +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Print warning and recommend using `buffer` v4.x which has an Object + * implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * We report that the browser does not support typed arrays if the are not subclassable + * using __proto__. Firefox 4-29 lacks support for adding new properties to `Uint8Array` + * (See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438). IE 10 lacks support + * for __proto__ and has a buggy typed array implementation. + */ +Buffer.TYPED_ARRAY_SUPPORT = typedArraySupport() + +if (!Buffer.TYPED_ARRAY_SUPPORT && typeof console !== 'undefined' && + typeof console.error === 'function') { + console.error( + 'This browser lacks typed array (Uint8Array) support which is required by ' + + '`buffer` v5.x. Use `buffer` v4.x if you require old browser support.' + ) +} + +function typedArraySupport () { + // Can typed array instances can be augmented? + try { + var arr = new Uint8Array(1) + arr.__proto__ = { __proto__: Uint8Array.prototype, foo: function () { return 42 } } + return arr.foo() === 42 + } catch (e) { + return false } +} - if (pos === undefined || pos === null) { - parent.boxes.push(box); - return; +Object.defineProperty(Buffer.prototype, 'parent', { + enumerable: true, + get: function () { + if (!Buffer.isBuffer(this)) return undefined + return this.buffer } +}) - var index = -1, - type; +Object.defineProperty(Buffer.prototype, 'offset', { + enumerable: true, + get: function () { + if (!Buffer.isBuffer(this)) return undefined + return this.byteOffset + } +}) - if (typeof pos === "number") { - index = pos; - } else { - if (typeof pos === "string") { - type = pos; - } else if (typeof pos === "object" && pos.type) { - type = pos.type; - } else { - parent.boxes.push(box); - return; - } +function createBuffer (length) { + if (length > K_MAX_LENGTH) { + throw new RangeError('The value "' + length + '" is invalid for option "size"') + } + // Return an augmented `Uint8Array` instance + var buf = new Uint8Array(length) + buf.__proto__ = Buffer.prototype + return buf +} - for (var i = 0; i < parent.boxes.length; i++) { - if (type === parent.boxes[i].type) { - index = i + 1; - break; - } +/** + * The Buffer constructor returns instances of `Uint8Array` that have their + * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of + * `Uint8Array`, so the returned instances will have all the node `Buffer` methods + * and the `Uint8Array` methods. Square bracket notation works as expected -- it + * returns a single octet. + * + * The `Uint8Array` prototype remains unmodified. + */ + +function Buffer (arg, encodingOrOffset, length) { + // Common case. + if (typeof arg === 'number') { + if (typeof encodingOrOffset === 'string') { + throw new TypeError( + 'The "string" argument must be of type string. Received type number' + ) } + return allocUnsafe(arg) } - parent.boxes.splice(index, 0, box); -}; + return from(arg, encodingOrOffset, length) +} -if (typeof exports !== 'undefined') { - exports.parseBuffer = ISOBoxer.parseBuffer; - exports.addBoxProcessor = ISOBoxer.addBoxProcessor; - exports.createFile = ISOBoxer.createFile; - exports.createBox = ISOBoxer.createBox; - exports.createFullBox = ISOBoxer.createFullBox; - exports.Utils = ISOBoxer.Utils; +// Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97 +if (typeof Symbol !== 'undefined' && Symbol.species != null && + Buffer[Symbol.species] === Buffer) { + Object.defineProperty(Buffer, Symbol.species, { + value: null, + configurable: true, + enumerable: false, + writable: false + }) } -ISOBoxer.Cursor = function(initialOffset) { - this.offset = (typeof initialOffset == 'undefined' ? 0 : initialOffset); -}; +Buffer.poolSize = 8192 // not used by this implementation -var ISOFile = function(arrayBuffer) { - this._cursor = new ISOBoxer.Cursor(); - this.boxes = []; - if (arrayBuffer) { - this._raw = new DataView(arrayBuffer); +function from (value, encodingOrOffset, length) { + if (typeof value === 'string') { + return fromString(value, encodingOrOffset) } -}; -ISOFile.prototype.fetch = function(type) { - var result = this.fetchAll(type, true); - return (result.length ? result[0] : null); -}; + if (ArrayBuffer.isView(value)) { + return fromArrayLike(value) + } -ISOFile.prototype.fetchAll = function(type, returnEarly) { - var result = []; - ISOFile._sweep.call(this, type, result, returnEarly); - return result; -}; + if (value == null) { + throw TypeError( + 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + + 'or Array-like Object. Received type ' + (typeof value) + ) + } -ISOFile.prototype.parse = function() { - this._cursor.offset = 0; - this.boxes = []; - while (this._cursor.offset < this._raw.byteLength) { - var box = ISOBox.parse(this); + if (isInstance(value, ArrayBuffer) || + (value && isInstance(value.buffer, ArrayBuffer))) { + return fromArrayBuffer(value, encodingOrOffset, length) + } - // Box could not be parsed - if (typeof box.type === 'undefined') break; + if (typeof value === 'number') { + throw new TypeError( + 'The "value" argument must not be of type number. Received type number' + ) + } - this.boxes.push(box); + var valueOf = value.valueOf && value.valueOf() + if (valueOf != null && valueOf !== value) { + return Buffer.from(valueOf, encodingOrOffset, length) } - return this; -}; -ISOFile._sweep = function(type, result, returnEarly) { - if (this.type && this.type == type) result.push(this); - for (var box in this.boxes) { - if (result.length && returnEarly) return; - ISOFile._sweep.call(this.boxes[box], type, result, returnEarly); + var b = fromObject(value) + if (b) return b + + if (typeof Symbol !== 'undefined' && Symbol.toPrimitive != null && + typeof value[Symbol.toPrimitive] === 'function') { + return Buffer.from( + value[Symbol.toPrimitive]('string'), encodingOrOffset, length + ) } -}; -ISOFile.prototype.write = function() { + throw new TypeError( + 'The first argument must be one of type string, Buffer, ArrayBuffer, Array, ' + + 'or Array-like Object. Received type ' + (typeof value) + ) +} - var length = 0, - i; +/** + * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError + * if value is a number. + * Buffer.from(str[, encoding]) + * Buffer.from(array) + * Buffer.from(buffer) + * Buffer.from(arrayBuffer[, byteOffset[, length]]) + **/ +Buffer.from = function (value, encodingOrOffset, length) { + return from(value, encodingOrOffset, length) +} - for (i = 0; i < this.boxes.length; i++) { - length += this.boxes[i].getLength(false); - } +// Note: Change prototype *after* Buffer.from is defined to workaround Chrome bug: +// https://github.com/feross/buffer/pull/148 +Buffer.prototype.__proto__ = Uint8Array.prototype +Buffer.__proto__ = Uint8Array - var bytes = new Uint8Array(length); - this._rawo = new DataView(bytes.buffer); - this.bytes = bytes; - this._cursor.offset = 0; +function assertSize (size) { + if (typeof size !== 'number') { + throw new TypeError('"size" argument must be of type number') + } else if (size < 0) { + throw new RangeError('The value "' + size + '" is invalid for option "size"') + } +} - for (i = 0; i < this.boxes.length; i++) { - this.boxes[i].write(); +function alloc (size, fill, encoding) { + assertSize(size) + if (size <= 0) { + return createBuffer(size) + } + if (fill !== undefined) { + // Only pay attention to encoding if it's a string. This + // prevents accidentally sending in a number that would + // be interpretted as a start offset. + return typeof encoding === 'string' + ? createBuffer(size).fill(fill, encoding) + : createBuffer(size).fill(fill) } + return createBuffer(size) +} - return bytes.buffer; -}; +/** + * Creates a new filled Buffer instance. + * alloc(size[, fill[, encoding]]) + **/ +Buffer.alloc = function (size, fill, encoding) { + return alloc(size, fill, encoding) +} -ISOFile.prototype.append = function(box, pos) { - ISOBoxer.Utils.appendBox(this, box, pos); -}; -var ISOBox = function() { - this._cursor = new ISOBoxer.Cursor(); -}; +function allocUnsafe (size) { + assertSize(size) + return createBuffer(size < 0 ? 0 : checked(size) | 0) +} -ISOBox.parse = function(parent) { - var newBox = new ISOBox(); - newBox._offset = parent._cursor.offset; - newBox._root = (parent._root ? parent._root : parent); - newBox._raw = parent._raw; - newBox._parent = parent; - newBox._parseBox(); - parent._cursor.offset = newBox._raw.byteOffset + newBox._raw.byteLength; - return newBox; -}; +/** + * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance. + * */ +Buffer.allocUnsafe = function (size) { + return allocUnsafe(size) +} +/** + * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance. + */ +Buffer.allocUnsafeSlow = function (size) { + return allocUnsafe(size) +} -ISOBox.create = function(type) { - var newBox = new ISOBox(); - newBox.type = type; - newBox.boxes = []; - return newBox; -}; +function fromString (string, encoding) { + if (typeof encoding !== 'string' || encoding === '') { + encoding = 'utf8' + } -ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca']; + if (!Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } -ISOBox.prototype._boxProcessors = {}; + var length = byteLength(string, encoding) | 0 + var buf = createBuffer(length) -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Generic read/write functions + var actual = buf.write(string, encoding) -ISOBox.prototype._procField = function (name, type, size) { - if (this._parsing) { - this[name] = this._readField(type, size); + if (actual !== length) { + // Writing a hex string, for example, that contains invalid characters will + // cause everything after the first invalid character to be ignored. (e.g. + // 'abxxcd' will be treated as 'ab') + buf = buf.slice(0, actual) } - else { - this._writeField(type, size, this[name]); - } -}; -ISOBox.prototype._procFieldArray = function (name, length, type, size) { - var i; - if (this._parsing) { - this[name] = []; - for (i = 0; i < length; i++) { - this[name][i] = this._readField(type, size); - } + return buf +} + +function fromArrayLike (array) { + var length = array.length < 0 ? 0 : checked(array.length) | 0 + var buf = createBuffer(length) + for (var i = 0; i < length; i += 1) { + buf[i] = array[i] & 255 } - else { - for (i = 0; i < this[name].length; i++) { - this._writeField(type, size, this[name][i]); - } + return buf +} + +function fromArrayBuffer (array, byteOffset, length) { + if (byteOffset < 0 || array.byteLength < byteOffset) { + throw new RangeError('"offset" is outside of buffer bounds') } -}; -ISOBox.prototype._procFullBox = function() { - this._procField('version', 'uint', 8); - this._procField('flags', 'uint', 24); -}; + if (array.byteLength < byteOffset + (length || 0)) { + throw new RangeError('"length" is outside of buffer bounds') + } -ISOBox.prototype._procEntries = function(name, length, fn) { - var i; - if (this._parsing) { - this[name] = []; - for (i = 0; i < length; i++) { - this[name].push({}); - fn.call(this, this[name][i]); - } + var buf + if (byteOffset === undefined && length === undefined) { + buf = new Uint8Array(array) + } else if (length === undefined) { + buf = new Uint8Array(array, byteOffset) + } else { + buf = new Uint8Array(array, byteOffset, length) } - else { - for (i = 0; i < length; i++) { - fn.call(this, this[name][i]); + + // Return an augmented `Uint8Array` instance + buf.__proto__ = Buffer.prototype + return buf +} + +function fromObject (obj) { + if (Buffer.isBuffer(obj)) { + var len = checked(obj.length) | 0 + var buf = createBuffer(len) + + if (buf.length === 0) { + return buf } + + obj.copy(buf, 0, 0, len) + return buf } -}; -ISOBox.prototype._procSubEntries = function(entry, name, length, fn) { - var i; - if (this._parsing) { - entry[name] = []; - for (i = 0; i < length; i++) { - entry[name].push({}); - fn.call(this, entry[name][i]); + if (obj.length !== undefined) { + if (typeof obj.length !== 'number' || numberIsNaN(obj.length)) { + return createBuffer(0) } + return fromArrayLike(obj) } - else { - for (i = 0; i < length; i++) { - fn.call(this, entry[name][i]); - } + + if (obj.type === 'Buffer' && Array.isArray(obj.data)) { + return fromArrayLike(obj.data) } -}; +} -ISOBox.prototype._procEntryField = function (entry, name, type, size) { - if (this._parsing) { - entry[name] = this._readField(type, size); +function checked (length) { + // Note: cannot use `length < K_MAX_LENGTH` here because that fails when + // length is NaN (which is otherwise coerced to zero.) + if (length >= K_MAX_LENGTH) { + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + K_MAX_LENGTH.toString(16) + ' bytes') } - else { - this._writeField(type, size, entry[name]); + return length | 0 +} + +function SlowBuffer (length) { + if (+length != length) { // eslint-disable-line eqeqeq + length = 0 } -}; + return Buffer.alloc(+length) +} -ISOBox.prototype._procSubBoxes = function(name, length) { - var i; - if (this._parsing) { - this[name] = []; - for (i = 0; i < length; i++) { - this[name].push(ISOBox.parse(this)); - } +Buffer.isBuffer = function isBuffer (b) { + return b != null && b._isBuffer === true && + b !== Buffer.prototype // so Buffer.isBuffer(Buffer.prototype) will be false +} + +Buffer.compare = function compare (a, b) { + if (isInstance(a, Uint8Array)) a = Buffer.from(a, a.offset, a.byteLength) + if (isInstance(b, Uint8Array)) b = Buffer.from(b, b.offset, b.byteLength) + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { + throw new TypeError( + 'The "buf1", "buf2" arguments must be one of type Buffer or Uint8Array' + ) } - else { - for (i = 0; i < length; i++) { - if (this._rawo) { - this[name][i].write(); - } else { - this.size += this[name][i].getLength(); - } + + if (a === b) return 0 + + var x = a.length + var y = b.length + + for (var i = 0, len = Math.min(x, y); i < len; ++i) { + if (a[i] !== b[i]) { + x = a[i] + y = b[i] + break } } -}; -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Read/parse functions + if (x < y) return -1 + if (y < x) return 1 + return 0 +} -ISOBox.prototype._readField = function(type, size) { - switch (type) { - case 'uint': - return this._readUint(size); - case 'int': - return this._readInt(size); - case 'template': - return this._readTemplate(size); - case 'string': - return (size === -1) ? this._readTerminatedString() : this._readString(size); - case 'data': - return this._readData(size); +Buffer.isEncoding = function isEncoding (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': case 'utf8': - return this._readUTF8String(); + case 'utf-8': + case 'ascii': + case 'latin1': + case 'binary': + case 'base64': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true default: - return -1; + return false } -}; +} -ISOBox.prototype._readInt = function(size) { - var result = null, - offset = this._cursor.offset - this._raw.byteOffset; - switch(size) { - case 8: - result = this._raw.getInt8(offset); - break; - case 16: - result = this._raw.getInt16(offset); - break; - case 32: - result = this._raw.getInt32(offset); - break; - case 64: - // Warning: JavaScript cannot handle 64-bit integers natively. - // This will give unexpected results for integers >= 2^53 - var s1 = this._raw.getInt32(offset); - var s2 = this._raw.getInt32(offset + 4); - result = (s1 * Math.pow(2,32)) + s2; - break; +Buffer.concat = function concat (list, length) { + if (!Array.isArray(list)) { + throw new TypeError('"list" argument must be an Array of Buffers') } - this._cursor.offset += (size >> 3); - return result; -}; -ISOBox.prototype._readUint = function(size) { - var result = null, - offset = this._cursor.offset - this._raw.byteOffset, - s1, s2; - switch(size) { - case 8: - result = this._raw.getUint8(offset); - break; - case 16: - result = this._raw.getUint16(offset); - break; - case 24: - s1 = this._raw.getUint16(offset); - s2 = this._raw.getUint8(offset + 2); - result = (s1 << 8) + s2; - break; - case 32: - result = this._raw.getUint32(offset); - break; - case 64: - // Warning: JavaScript cannot handle 64-bit integers natively. - // This will give unexpected results for integers >= 2^53 - s1 = this._raw.getUint32(offset); - s2 = this._raw.getUint32(offset + 4); - result = (s1 * Math.pow(2,32)) + s2; - break; + if (list.length === 0) { + return Buffer.alloc(0) } - this._cursor.offset += (size >> 3); - return result; -}; -ISOBox.prototype._readString = function(length) { - var str = ''; - for (var c = 0; c < length; c++) { - var char = this._readUint(8); - str += String.fromCharCode(char); + var i + if (length === undefined) { + length = 0 + for (i = 0; i < list.length; ++i) { + length += list[i].length + } } - return str; -}; - -ISOBox.prototype._readTemplate = function(size) { - var pre = this._readUint(size / 2); - var post = this._readUint(size / 2); - return pre + (post / Math.pow(2, size / 2)); -}; -ISOBox.prototype._readTerminatedString = function() { - var str = ''; - while (this._cursor.offset - this._offset < this._raw.byteLength) { - var char = this._readUint(8); - if (char === 0) break; - str += String.fromCharCode(char); + var buffer = Buffer.allocUnsafe(length) + var pos = 0 + for (i = 0; i < list.length; ++i) { + var buf = list[i] + if (isInstance(buf, Uint8Array)) { + buf = Buffer.from(buf) + } + if (!Buffer.isBuffer(buf)) { + throw new TypeError('"list" argument must be an Array of Buffers') + } + buf.copy(buffer, pos) + pos += buf.length } - return str; -}; - -ISOBox.prototype._readData = function(size) { - var length = (size > 0) ? size : (this._raw.byteLength - (this._cursor.offset - this._offset)); - if (length > 0) { - var data = new Uint8Array(this._raw.buffer, this._cursor.offset, length); + return buffer +} - this._cursor.offset += length; - return data; +function byteLength (string, encoding) { + if (Buffer.isBuffer(string)) { + return string.length } - else { - return null; + if (ArrayBuffer.isView(string) || isInstance(string, ArrayBuffer)) { + return string.byteLength } -}; - -ISOBox.prototype._readUTF8String = function() { - var length = this._raw.byteLength - (this._cursor.offset - this._offset); - var data = null; - if (length > 0) { - data = new DataView(this._raw.buffer, this._cursor.offset, length); - this._cursor.offset += length; + if (typeof string !== 'string') { + throw new TypeError( + 'The "string" argument must be one of type string, Buffer, or ArrayBuffer. ' + + 'Received type ' + typeof string + ) } - - return data ? ISOBoxer.Utils.dataViewToString(data) : data; -}; -ISOBox.prototype._parseBox = function() { - this._parsing = true; - this._cursor.offset = this._offset; + var len = string.length + var mustMatch = (arguments.length > 2 && arguments[2] === true) + if (!mustMatch && len === 0) return 0 - // return immediately if there are not enough bytes to read the header - if (this._offset + 8 > this._raw.buffer.byteLength) { - this._root._incomplete = true; - return; + // Use a for loop to avoid recursion + var loweredCase = false + for (;;) { + switch (encoding) { + case 'ascii': + case 'latin1': + case 'binary': + return len + case 'utf8': + case 'utf-8': + return utf8ToBytes(string).length + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return len * 2 + case 'hex': + return len >>> 1 + case 'base64': + return base64ToBytes(string).length + default: + if (loweredCase) { + return mustMatch ? -1 : utf8ToBytes(string).length // assume utf8 + } + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } } +} +Buffer.byteLength = byteLength - this._procField('size', 'uint', 32); - this._procField('type', 'string', 4); +function slowToString (encoding, start, end) { + var loweredCase = false - if (this.size === 1) { this._procField('largesize', 'uint', 64); } - if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } + // No need to verify that "this.length <= MAX_UINT32" since it's a read-only + // property of a typed array. - switch(this.size) { - case 0: - this._raw = new DataView(this._raw.buffer, this._offset, (this._raw.byteLength - this._cursor.offset + 8)); - break; - case 1: - if (this._offset + this.size > this._raw.buffer.byteLength) { - this._incomplete = true; - this._root._incomplete = true; - } else { - this._raw = new DataView(this._raw.buffer, this._offset, this.largesize); - } - break; - default: - if (this._offset + this.size > this._raw.buffer.byteLength) { - this._incomplete = true; - this._root._incomplete = true; - } else { - this._raw = new DataView(this._raw.buffer, this._offset, this.size); - } + // This behaves neither like String nor Uint8Array in that we set start/end + // to their upper/lower bounds if the value passed is out of range. + // undefined is handled specially as per ECMA-262 6th Edition, + // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization. + if (start === undefined || start < 0) { + start = 0 + } + // Return early if start > this.length. Done here to prevent potential uint32 + // coercion fail below. + if (start > this.length) { + return '' } - // additional parsing - if (!this._incomplete) { - if (this._boxProcessors[this.type]) { - this._boxProcessors[this.type].call(this); - } - if (this._boxContainers.indexOf(this.type) !== -1) { - this._parseContainerBox(); - } else{ - // Unknown box => read and store box content - this._data = this._readData(); - } + if (end === undefined || end > this.length) { + end = this.length } -}; -ISOBox.prototype._parseFullBox = function() { - this.version = this._readUint(8); - this.flags = this._readUint(24); -}; + if (end <= 0) { + return '' + } -ISOBox.prototype._parseContainerBox = function() { - this.boxes = []; - while (this._cursor.offset - this._raw.byteOffset < this._raw.byteLength) { - this.boxes.push(ISOBox.parse(this)); + // Force coersion to uint32. This will also coerce falsey/NaN values to 0. + end >>>= 0 + start >>>= 0 + + if (end <= start) { + return '' } -}; -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Write functions + if (!encoding) encoding = 'utf8' -ISOBox.prototype.append = function(box, pos) { - ISOBoxer.Utils.appendBox(this, box, pos); -}; + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) -ISOBox.prototype.getLength = function() { - this._parsing = false; - this._rawo = null; + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) - this.size = 0; - this._procField('size', 'uint', 32); - this._procField('type', 'string', 4); + case 'ascii': + return asciiSlice(this, start, end) - if (this.size === 1) { this._procField('largesize', 'uint', 64); } - if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } + case 'latin1': + case 'binary': + return latin1Slice(this, start, end) - if (this._boxProcessors[this.type]) { - this._boxProcessors[this.type].call(this); - } + case 'base64': + return base64Slice(this, start, end) - if (this._boxContainers.indexOf(this.type) !== -1) { - for (var i = 0; i < this.boxes.length; i++) { - this.size += this.boxes[i].getLength(); - } - } + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) - if (this._data) { - this._writeData(this._data); + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true + } } +} - return this.size; -}; +// This property is used by `Buffer.isBuffer` (and the `is-buffer` npm package) +// to detect a Buffer instance. It's not possible to use `instanceof Buffer` +// reliably in a browserify context because there could be multiple different +// copies of the 'buffer' package in use. This method works even for Buffer +// instances that were created from another copy of the `buffer` package. +// See: https://github.com/feross/buffer/issues/154 +Buffer.prototype._isBuffer = true -ISOBox.prototype.write = function() { - this._parsing = false; - this._cursor.offset = this._parent._cursor.offset; +function swap (b, n, m) { + var i = b[n] + b[n] = b[m] + b[m] = i +} - switch(this.size) { - case 0: - this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, (this.parent._rawo.byteLength - this._cursor.offset)); - break; - case 1: - this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.largesize); - break; - default: - this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.size); +Buffer.prototype.swap16 = function swap16 () { + var len = this.length + if (len % 2 !== 0) { + throw new RangeError('Buffer size must be a multiple of 16-bits') } + for (var i = 0; i < len; i += 2) { + swap(this, i, i + 1) + } + return this +} - this._procField('size', 'uint', 32); - this._procField('type', 'string', 4); - - if (this.size === 1) { this._procField('largesize', 'uint', 64); } - if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } +Buffer.prototype.swap32 = function swap32 () { + var len = this.length + if (len % 4 !== 0) { + throw new RangeError('Buffer size must be a multiple of 32-bits') + } + for (var i = 0; i < len; i += 4) { + swap(this, i, i + 3) + swap(this, i + 1, i + 2) + } + return this +} - if (this._boxProcessors[this.type]) { - this._boxProcessors[this.type].call(this); +Buffer.prototype.swap64 = function swap64 () { + var len = this.length + if (len % 8 !== 0) { + throw new RangeError('Buffer size must be a multiple of 64-bits') + } + for (var i = 0; i < len; i += 8) { + swap(this, i, i + 7) + swap(this, i + 1, i + 6) + swap(this, i + 2, i + 5) + swap(this, i + 3, i + 4) } + return this +} - if (this._boxContainers.indexOf(this.type) !== -1) { - for (var i = 0; i < this.boxes.length; i++) { - this.boxes[i].write(); - } - } +Buffer.prototype.toString = function toString () { + var length = this.length + if (length === 0) return '' + if (arguments.length === 0) return utf8Slice(this, 0, length) + return slowToString.apply(this, arguments) +} - if (this._data) { - this._writeData(this._data); +Buffer.prototype.toLocaleString = Buffer.prototype.toString + +Buffer.prototype.equals = function equals (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + if (this === b) return true + return Buffer.compare(this, b) === 0 +} + +Buffer.prototype.inspect = function inspect () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + str = this.toString('hex', 0, max).replace(/(.{2})/g, '$1 ').trim() + if (this.length > max) str += ' ... ' + return '' +} + +Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { + if (isInstance(target, Uint8Array)) { + target = Buffer.from(target, target.offset, target.byteLength) + } + if (!Buffer.isBuffer(target)) { + throw new TypeError( + 'The "target" argument must be one of type Buffer or Uint8Array. ' + + 'Received type ' + (typeof target) + ) } - this._parent._cursor.offset += this.size; + if (start === undefined) { + start = 0 + } + if (end === undefined) { + end = target ? target.length : 0 + } + if (thisStart === undefined) { + thisStart = 0 + } + if (thisEnd === undefined) { + thisEnd = this.length + } - return this.size; -}; + if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) { + throw new RangeError('out of range index') + } -ISOBox.prototype._writeInt = function(size, value) { - if (this._rawo) { - var offset = this._cursor.offset - this._rawo.byteOffset; - switch(size) { - case 8: - this._rawo.setInt8(offset, value); - break; - case 16: - this._rawo.setInt16(offset, value); - break; - case 32: - this._rawo.setInt32(offset, value); - break; - case 64: - // Warning: JavaScript cannot handle 64-bit integers natively. - // This will give unexpected results for integers >= 2^53 - var s1 = Math.floor(value / Math.pow(2,32)); - var s2 = value - (s1 * Math.pow(2,32)); - this._rawo.setUint32(offset, s1); - this._rawo.setUint32(offset + 4, s2); - break; - } - this._cursor.offset += (size >> 3); - } else { - this.size += (size >> 3); + if (thisStart >= thisEnd && start >= end) { + return 0 + } + if (thisStart >= thisEnd) { + return -1 + } + if (start >= end) { + return 1 } -}; -ISOBox.prototype._writeUint = function(size, value) { + start >>>= 0 + end >>>= 0 + thisStart >>>= 0 + thisEnd >>>= 0 - if (this._rawo) { - var offset = this._cursor.offset - this._rawo.byteOffset, - s1, s2; - switch(size) { - case 8: - this._rawo.setUint8(offset, value); - break; - case 16: - this._rawo.setUint16(offset, value); - break; - case 24: - s1 = (value & 0xFFFF00) >> 8; - s2 = (value & 0x0000FF); - this._rawo.setUint16(offset, s1); - this._rawo.setUint8(offset + 2, s2); - break; - case 32: - this._rawo.setUint32(offset, value); - break; - case 64: - // Warning: JavaScript cannot handle 64-bit integers natively. - // This will give unexpected results for integers >= 2^53 - s1 = Math.floor(value / Math.pow(2,32)); - s2 = value - (s1 * Math.pow(2,32)); - this._rawo.setUint32(offset, s1); - this._rawo.setUint32(offset + 4, s2); - break; + if (this === target) return 0 + + var x = thisEnd - thisStart + var y = end - start + var len = Math.min(x, y) + + var thisCopy = this.slice(thisStart, thisEnd) + var targetCopy = target.slice(start, end) + + for (var i = 0; i < len; ++i) { + if (thisCopy[i] !== targetCopy[i]) { + x = thisCopy[i] + y = targetCopy[i] + break } - this._cursor.offset += (size >> 3); - } else { - this.size += (size >> 3); } -}; -ISOBox.prototype._writeString = function(size, str) { - for (var c = 0; c < size; c++) { - this._writeUint(8, str.charCodeAt(c)); - } -}; + if (x < y) return -1 + if (y < x) return 1 + return 0 +} -ISOBox.prototype._writeTerminatedString = function(str) { - if (str.length === 0) { - return; +// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`, +// OR the last index of `val` in `buffer` at offset <= `byteOffset`. +// +// Arguments: +// - buffer - a Buffer to search +// - val - a string, Buffer, or number +// - byteOffset - an index into `buffer`; will be clamped to an int32 +// - encoding - an optional encoding, relevant is val is a string +// - dir - true for indexOf, false for lastIndexOf +function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { + // Empty buffer means no match + if (buffer.length === 0) return -1 + + // Normalize byteOffset + if (typeof byteOffset === 'string') { + encoding = byteOffset + byteOffset = 0 + } else if (byteOffset > 0x7fffffff) { + byteOffset = 0x7fffffff + } else if (byteOffset < -0x80000000) { + byteOffset = -0x80000000 + } + byteOffset = +byteOffset // Coerce to Number. + if (numberIsNaN(byteOffset)) { + // byteOffset: it it's undefined, null, NaN, "foo", etc, search whole buffer + byteOffset = dir ? 0 : (buffer.length - 1) + } + + // Normalize byteOffset: negative offsets start from the end of the buffer + if (byteOffset < 0) byteOffset = buffer.length + byteOffset + if (byteOffset >= buffer.length) { + if (dir) return -1 + else byteOffset = buffer.length - 1 + } else if (byteOffset < 0) { + if (dir) byteOffset = 0 + else return -1 + } + + // Normalize val + if (typeof val === 'string') { + val = Buffer.from(val, encoding) } - for (var c = 0; c < str.length; c++) { - this._writeUint(8, str.charCodeAt(c)); + + // Finally, search either indexOf (if dir is true) or lastIndexOf + if (Buffer.isBuffer(val)) { + // Special case: looking for empty string/buffer always fails + if (val.length === 0) { + return -1 + } + return arrayIndexOf(buffer, val, byteOffset, encoding, dir) + } else if (typeof val === 'number') { + val = val & 0xFF // Search for a byte value [0-255] + if (typeof Uint8Array.prototype.indexOf === 'function') { + if (dir) { + return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset) + } else { + return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) + } + } + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) } - this._writeUint(8, 0); -}; -ISOBox.prototype._writeTemplate = function(size, value) { - var pre = Math.floor(value); - var post = (value - pre) * Math.pow(2, size / 2); - this._writeUint(size / 2, pre); - this._writeUint(size / 2, post); -}; + throw new TypeError('val must be string, number or Buffer') +} -ISOBox.prototype._writeData = function(data) { - var i; - //data to copy - if (data) { - if (this._rawo) { - //Array and Uint8Array has also to be managed - if (data instanceof Array) { - var offset = this._cursor.offset - this._rawo.byteOffset; - for (var i = 0; i < data.length; i++) { - this._rawo.setInt8(offset + i, data[i]); - } - this._cursor.offset += data.length; - } +function arrayIndexOf (arr, val, byteOffset, encoding, dir) { + var indexSize = 1 + var arrLength = arr.length + var valLength = val.length - if (data instanceof Uint8Array) { - this._root.bytes.set(data, this._cursor.offset); - this._cursor.offset += data.length; + if (encoding !== undefined) { + encoding = String(encoding).toLowerCase() + if (encoding === 'ucs2' || encoding === 'ucs-2' || + encoding === 'utf16le' || encoding === 'utf-16le') { + if (arr.length < 2 || val.length < 2) { + return -1 } - - } else { - //nothing to copy only size to compute - this.size += data.length; + indexSize = 2 + arrLength /= 2 + valLength /= 2 + byteOffset /= 2 } } -}; -ISOBox.prototype._writeUTF8String = function(string) { - var u = ISOBoxer.Utils.utf8ToByteArray(string); - if (this._rawo) { - var dataView = new DataView(this._rawo.buffer, this._cursor.offset, u.length); - for (var i = 0; i < u.length; i++) { - dataView.setUint8(i, u[i]); + function read (buf, i) { + if (indexSize === 1) { + return buf[i] + } else { + return buf.readUInt16BE(i * indexSize) } - } else { - this.size += u.length; } -}; -ISOBox.prototype._writeField = function(type, size, value) { - switch (type) { - case 'uint': - this._writeUint(size, value); - break; - case 'int': - this._writeInt(size, value); - break; - case 'template': - this._writeTemplate(size, value); - break; - case 'string': - if (size == -1) { - this._writeTerminatedString(value); + var i + if (dir) { + var foundIndex = -1 + for (i = byteOffset; i < arrLength; i++) { + if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) { + if (foundIndex === -1) foundIndex = i + if (i - foundIndex + 1 === valLength) return foundIndex * indexSize } else { - this._writeString(size, value); + if (foundIndex !== -1) i -= i - foundIndex + foundIndex = -1 } - break; - case 'data': - this._writeData(value); - break; - case 'utf8': - this._writeUTF8String(value); - break; - default: - break; + } + } else { + if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength + for (i = byteOffset; i >= 0; i--) { + var found = true + for (var j = 0; j < valLength; j++) { + if (read(arr, i + j) !== read(val, j)) { + found = false + break + } + } + if (found) return i + } } -}; - -// ISO/IEC 14496-15:2014 - avc1 box -ISOBox.prototype._boxProcessors['avc1'] = ISOBox.prototype._boxProcessors['encv'] = function() { - // SampleEntry fields - this._procFieldArray('reserved1', 6, 'uint', 8); - this._procField('data_reference_index', 'uint', 16); - // VisualSampleEntry fields - this._procField('pre_defined1', 'uint', 16); - this._procField('reserved2', 'uint', 16); - this._procFieldArray('pre_defined2', 3, 'uint', 32); - this._procField('width', 'uint', 16); - this._procField('height', 'uint', 16); - this._procField('horizresolution', 'template', 32); - this._procField('vertresolution', 'template', 32); - this._procField('reserved3', 'uint', 32); - this._procField('frame_count', 'uint', 16); - this._procFieldArray('compressorname', 32,'uint', 8); - this._procField('depth', 'uint', 16); - this._procField('pre_defined3', 'int', 16); - // AVCSampleEntry fields - this._procField('config', 'data', -1); -}; -// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box -ISOBox.prototype._boxProcessors['dref'] = function() { - this._procFullBox(); - this._procField('entry_count', 'uint', 32); - this._procSubBoxes('entries', this.entry_count); -}; + return -1 +} -// ISO/IEC 14496-12:2012 - 8.6.6 Edit List Box -ISOBox.prototype._boxProcessors['elst'] = function() { - this._procFullBox(); - this._procField('entry_count', 'uint', 32); - this._procEntries('entries', this.entry_count, function(entry) { - this._procEntryField(entry, 'segment_duration', 'uint', (this.version === 1) ? 64 : 32); - this._procEntryField(entry, 'media_time', 'int', (this.version === 1) ? 64 : 32); - this._procEntryField(entry, 'media_rate_integer', 'int', 16); - this._procEntryField(entry, 'media_rate_fraction', 'int', 16); - }); -}; +Buffer.prototype.includes = function includes (val, byteOffset, encoding) { + return this.indexOf(val, byteOffset, encoding) !== -1 +} -// ISO/IEC 23009-1:2014 - 5.10.3.3 Event Message Box -ISOBox.prototype._boxProcessors['emsg'] = function() { - this._procFullBox(); - this._procField('scheme_id_uri', 'string', -1); - this._procField('value', 'string', -1); - this._procField('timescale', 'uint', 32); - this._procField('presentation_time_delta', 'uint', 32); - this._procField('event_duration', 'uint', 32); - this._procField('id', 'uint', 32); - this._procField('message_data', 'data', -1); -}; +Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, true) +} -// ISO/IEC 14496-12:2012 - 8.1.2 Free Space Box -ISOBox.prototype._boxProcessors['free'] = ISOBox.prototype._boxProcessors['skip'] = function() { - this._procField('data', 'data', -1); -}; +Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { + return bidirectionalIndexOf(this, val, byteOffset, encoding, false) +} -// ISO/IEC 14496-12:2012 - 8.12.2 Original Format Box -ISOBox.prototype._boxProcessors['frma'] = function() { - this._procField('data_format', 'uint', 32); -}; -// ISO/IEC 14496-12:2012 - 4.3 File Type Box / 8.16.2 Segment Type Box -ISOBox.prototype._boxProcessors['ftyp'] = -ISOBox.prototype._boxProcessors['styp'] = function() { - this._procField('major_brand', 'string', 4); - this._procField('minor_version', 'uint', 32); - var nbCompatibleBrands = -1; - if (this._parsing) { - nbCompatibleBrands = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset)) / 4; +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } } - this._procFieldArray('compatible_brands', nbCompatibleBrands, 'string', 4); -}; - -// ISO/IEC 14496-12:2012 - 8.4.3 Handler Reference Box -ISOBox.prototype._boxProcessors['hdlr'] = function() { - this._procFullBox(); - this._procField('pre_defined', 'uint', 32); - this._procField('handler_type', 'string', 4); - this._procFieldArray('reserved', 3, 'uint', 32); - this._procField('name', 'string', -1); -}; -// ISO/IEC 14496-12:2012 - 8.1.1 Media Data Box -ISOBox.prototype._boxProcessors['mdat'] = function() { - this._procField('data', 'data', -1); -}; + var strLen = string.length -// ISO/IEC 14496-12:2012 - 8.4.2 Media Header Box -ISOBox.prototype._boxProcessors['mdhd'] = function() { - this._procFullBox(); - this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); - this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); - this._procField('timescale', 'uint', 32); - this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); - if (!this._parsing && typeof this.language === 'string') { - // In case of writing and language has been set as a string, then convert it into char codes array - this.language = ((this.language.charCodeAt(0) - 0x60) << 10) | - ((this.language.charCodeAt(1) - 0x60) << 5) | - ((this.language.charCodeAt(2) - 0x60)); + if (length > strLen / 2) { + length = strLen / 2 } - this._procField('language', 'uint', 16); - if (this._parsing) { - this.language = String.fromCharCode(((this.language >> 10) & 0x1F) + 0x60, - ((this.language >> 5) & 0x1F) + 0x60, - (this.language & 0x1F) + 0x60); + for (var i = 0; i < length; ++i) { + var parsed = parseInt(string.substr(i * 2, 2), 16) + if (numberIsNaN(parsed)) return i + buf[offset + i] = parsed } - this._procField('pre_defined', 'uint', 16); -}; - -// ISO/IEC 14496-12:2012 - 8.8.2 Movie Extends Header Box -ISOBox.prototype._boxProcessors['mehd'] = function() { - this._procFullBox(); - this._procField('fragment_duration', 'uint', (this.version == 1) ? 64 : 32); -}; - -// ISO/IEC 14496-12:2012 - 8.8.5 Movie Fragment Header Box -ISOBox.prototype._boxProcessors['mfhd'] = function() { - this._procFullBox(); - this._procField('sequence_number', 'uint', 32); -}; - -// ISO/IEC 14496-12:2012 - 8.8.11 Movie Fragment Random Access Box -ISOBox.prototype._boxProcessors['mfro'] = function() { - this._procFullBox(); - this._procField('mfra_size', 'uint', 32); // Called mfra_size to distinguish from the normal "size" attribute of a box -}; + return i +} +function utf8Write (buf, string, offset, length) { + return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) +} -// ISO/IEC 14496-12:2012 - 8.5.2.2 mp4a box (use AudioSampleEntry definition and naming) -ISOBox.prototype._boxProcessors['mp4a'] = ISOBox.prototype._boxProcessors['enca'] = function() { - // SampleEntry fields - this._procFieldArray('reserved1', 6, 'uint', 8); - this._procField('data_reference_index', 'uint', 16); - // AudioSampleEntry fields - this._procFieldArray('reserved2', 2, 'uint', 32); - this._procField('channelcount', 'uint', 16); - this._procField('samplesize', 'uint', 16); - this._procField('pre_defined', 'uint', 16); - this._procField('reserved3', 'uint', 16); - this._procField('samplerate', 'template', 32); - // ESDescriptor fields - this._procField('esds', 'data', -1); -}; +function asciiWrite (buf, string, offset, length) { + return blitBuffer(asciiToBytes(string), buf, offset, length) +} -// ISO/IEC 14496-12:2012 - 8.2.2 Movie Header Box -ISOBox.prototype._boxProcessors['mvhd'] = function() { - this._procFullBox(); - this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); - this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); - this._procField('timescale', 'uint', 32); - this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); - this._procField('rate', 'template', 32); - this._procField('volume', 'template', 16); - this._procField('reserved1', 'uint', 16); - this._procFieldArray('reserved2', 2, 'uint', 32); - this._procFieldArray('matrix', 9, 'template', 32); - this._procFieldArray('pre_defined', 6,'uint', 32); - this._procField('next_track_ID', 'uint', 32); -}; +function latin1Write (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} -// ISO/IEC 14496-30:2014 - WebVTT Cue Payload Box. -ISOBox.prototype._boxProcessors['payl'] = function() { - this._procField('cue_text', 'utf8'); -}; +function base64Write (buf, string, offset, length) { + return blitBuffer(base64ToBytes(string), buf, offset, length) +} -//ISO/IEC 23001-7:2011 - 8.1 Protection System Specific Header Box -ISOBox.prototype._boxProcessors['pssh'] = function() { - this._procFullBox(); - - this._procFieldArray('SystemID', 16, 'uint', 8); - this._procField('DataSize', 'uint', 32); - this._procFieldArray('Data', this.DataSize, 'uint', 8); -}; -// ISO/IEC 14496-12:2012 - 8.12.5 Scheme Type Box -ISOBox.prototype._boxProcessors['schm'] = function() { - this._procFullBox(); - - this._procField('scheme_type', 'uint', 32); - this._procField('scheme_version', 'uint', 32); +function ucs2Write (buf, string, offset, length) { + return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) +} - if (this.flags & 0x000001) { - this._procField('scheme_uri', 'string', -1); +Buffer.prototype.write = function write (string, offset, length, encoding) { + // Buffer#write(string) + if (offset === undefined) { + encoding = 'utf8' + length = this.length + offset = 0 + // Buffer#write(string, encoding) + } else if (length === undefined && typeof offset === 'string') { + encoding = offset + length = this.length + offset = 0 + // Buffer#write(string, offset[, length][, encoding]) + } else if (isFinite(offset)) { + offset = offset >>> 0 + if (isFinite(length)) { + length = length >>> 0 + if (encoding === undefined) encoding = 'utf8' + } else { + encoding = length + length = undefined } -}; -// ISO/IEC 14496-12:2012 - 8.6.4.1 sdtp box -ISOBox.prototype._boxProcessors['sdtp'] = function() { - this._procFullBox(); - - var sample_count = -1; - if (this._parsing) { - sample_count = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset)); + } else { + throw new Error( + 'Buffer.write(string, encoding, offset[, length]) is no longer supported' + ) } - this._procFieldArray('sample_dependency_table', sample_count, 'uint', 8); -}; + var remaining = this.length - offset + if (length === undefined || length > remaining) length = remaining -// ISO/IEC 14496-12:2012 - 8.16.3 Segment Index Box -ISOBox.prototype._boxProcessors['sidx'] = function() { - this._procFullBox(); - this._procField('reference_ID', 'uint', 32); - this._procField('timescale', 'uint', 32); - this._procField('earliest_presentation_time', 'uint', (this.version == 1) ? 64 : 32); - this._procField('first_offset', 'uint', (this.version == 1) ? 64 : 32); - this._procField('reserved', 'uint', 16); - this._procField('reference_count', 'uint', 16); - this._procEntries('references', this.reference_count, function(entry) { - if (!this._parsing) { - entry.reference = (entry.reference_type & 0x00000001) << 31; - entry.reference |= (entry.referenced_size & 0x7FFFFFFF); - entry.sap = (entry.starts_with_SAP & 0x00000001) << 31; - entry.sap |= (entry.SAP_type & 0x00000003) << 28; - entry.sap |= (entry.SAP_delta_time & 0x0FFFFFFF); - } - this._procEntryField(entry, 'reference', 'uint', 32); - this._procEntryField(entry, 'subsegment_duration', 'uint', 32); - this._procEntryField(entry, 'sap', 'uint', 32); - if (this._parsing) { - entry.reference_type = (entry.reference >> 31) & 0x00000001; - entry.referenced_size = entry.reference & 0x7FFFFFFF; - entry.starts_with_SAP = (entry.sap >> 31) & 0x00000001; - entry.SAP_type = (entry.sap >> 28) & 0x00000007; - entry.SAP_delta_time = (entry.sap & 0x0FFFFFFF); - } - }); -}; + if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { + throw new RangeError('Attempt to write outside buffer bounds') + } -// ISO/IEC 14496-12:2012 - 8.4.5.3 Sound Media Header Box -ISOBox.prototype._boxProcessors['smhd'] = function() { - this._procFullBox(); - this._procField('balance', 'uint', 16); - this._procField('reserved', 'uint', 16); -}; + if (!encoding) encoding = 'utf8' -// ISO/IEC 14496-12:2012 - 8.16.4 Subsegment Index Box -ISOBox.prototype._boxProcessors['ssix'] = function() { - this._procFullBox(); - this._procField('subsegment_count', 'uint', 32); - this._procEntries('subsegments', this.subsegment_count, function(subsegment) { - this._procEntryField(subsegment, 'ranges_count', 'uint', 32); - this._procSubEntries(subsegment, 'ranges', subsegment.ranges_count, function(range) { - this._procEntryField(range, 'level', 'uint', 8); - this._procEntryField(range, 'range_size', 'uint', 24); - }); - }); -}; + var loweredCase = false + for (;;) { + switch (encoding) { + case 'hex': + return hexWrite(this, string, offset, length) -// ISO/IEC 14496-12:2012 - 8.5.2 Sample Description Box -ISOBox.prototype._boxProcessors['stsd'] = function() { - this._procFullBox(); - this._procField('entry_count', 'uint', 32); - this._procSubBoxes('entries', this.entry_count); -}; + case 'utf8': + case 'utf-8': + return utf8Write(this, string, offset, length) -// ISO/IEC 14496-12:2015 - 8.7.7 Sub-Sample Information Box -ISOBox.prototype._boxProcessors['subs'] = function () { - this._procFullBox(); - this._procField('entry_count', 'uint', 32); - this._procEntries('entries', this.entry_count, function(entry) { - this._procEntryField(entry, 'sample_delta', 'uint', 32); - this._procEntryField(entry, 'subsample_count', 'uint', 16); - this._procSubEntries(entry, 'subsamples', entry.subsample_count, function(subsample) { - this._procEntryField(subsample, 'subsample_size', 'uint', (this.version === 1) ? 32 : 16); - this._procEntryField(subsample, 'subsample_priority', 'uint', 8); - this._procEntryField(subsample, 'discardable', 'uint', 8); - this._procEntryField(subsample, 'codec_specific_parameters', 'uint', 32); - }); - }); -}; + case 'ascii': + return asciiWrite(this, string, offset, length) -//ISO/IEC 23001-7:2011 - 8.2 Track Encryption Box -ISOBox.prototype._boxProcessors['tenc'] = function() { - this._procFullBox(); + case 'latin1': + case 'binary': + return latin1Write(this, string, offset, length) - this._procField('default_IsEncrypted', 'uint', 24); - this._procField('default_IV_size', 'uint', 8); - this._procFieldArray('default_KID', 16, 'uint', 8); - }; + case 'base64': + // Warning: maxLength not taken into account in base64Write + return base64Write(this, string, offset, length) -// ISO/IEC 14496-12:2012 - 8.8.12 Track Fragmnent Decode Time -ISOBox.prototype._boxProcessors['tfdt'] = function() { - this._procFullBox(); - this._procField('baseMediaDecodeTime', 'uint', (this.version == 1) ? 64 : 32); -}; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return ucs2Write(this, string, offset, length) -// ISO/IEC 14496-12:2012 - 8.8.7 Track Fragment Header Box -ISOBox.prototype._boxProcessors['tfhd'] = function() { - this._procFullBox(); - this._procField('track_ID', 'uint', 32); - if (this.flags & 0x01) this._procField('base_data_offset', 'uint', 64); - if (this.flags & 0x02) this._procField('sample_description_offset', 'uint', 32); - if (this.flags & 0x08) this._procField('default_sample_duration', 'uint', 32); - if (this.flags & 0x10) this._procField('default_sample_size', 'uint', 32); - if (this.flags & 0x20) this._procField('default_sample_flags', 'uint', 32); -}; + default: + if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) + encoding = ('' + encoding).toLowerCase() + loweredCase = true + } + } +} -// ISO/IEC 14496-12:2012 - 8.8.10 Track Fragment Random Access Box -ISOBox.prototype._boxProcessors['tfra'] = function() { - this._procFullBox(); - this._procField('track_ID', 'uint', 32); - if (!this._parsing) { - this.reserved = 0; - this.reserved |= (this.length_size_of_traf_num & 0x00000030) << 4; - this.reserved |= (this.length_size_of_trun_num & 0x0000000C) << 2; - this.reserved |= (this.length_size_of_sample_num & 0x00000003); +Buffer.prototype.toJSON = function toJSON () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) } - this._procField('reserved', 'uint', 32); - if (this._parsing) { - this.length_size_of_traf_num = (this.reserved & 0x00000030) >> 4; - this.length_size_of_trun_num = (this.reserved & 0x0000000C) >> 2; - this.length_size_of_sample_num = (this.reserved & 0x00000003); +} + +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) } - this._procField('number_of_entry', 'uint', 32); - this._procEntries('entries', this.number_of_entry, function(entry) { - this._procEntryField(entry, 'time', 'uint', (this.version === 1) ? 64 : 32); - this._procEntryField(entry, 'moof_offset', 'uint', (this.version === 1) ? 64 : 32); - this._procEntryField(entry, 'traf_number', 'uint', (this.length_size_of_traf_num + 1) * 8); - this._procEntryField(entry, 'trun_number', 'uint', (this.length_size_of_trun_num + 1) * 8); - this._procEntryField(entry, 'sample_number', 'uint', (this.length_size_of_sample_num + 1) * 8); - }); -}; +} -// ISO/IEC 14496-12:2012 - 8.3.2 Track Header Box -ISOBox.prototype._boxProcessors['tkhd'] = function() { - this._procFullBox(); - this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); - this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); - this._procField('track_ID', 'uint', 32); - this._procField('reserved1', 'uint', 32); - this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); - this._procFieldArray('reserved2', 2, 'uint', 32); - this._procField('layer', 'uint', 16); - this._procField('alternate_group', 'uint', 16); - this._procField('volume', 'template', 16); - this._procField('reserved3', 'uint', 16); - this._procFieldArray('matrix', 9, 'template', 32); - this._procField('width', 'template', 32); - this._procField('height', 'template', 32); -}; +function utf8Slice (buf, start, end) { + end = Math.min(buf.length, end) + var res = [] -// ISO/IEC 14496-12:2012 - 8.8.3 Track Extends Box -ISOBox.prototype._boxProcessors['trex'] = function() { - this._procFullBox(); - this._procField('track_ID', 'uint', 32); - this._procField('default_sample_description_index', 'uint', 32); - this._procField('default_sample_duration', 'uint', 32); - this._procField('default_sample_size', 'uint', 32); - this._procField('default_sample_flags', 'uint', 32); -}; + var i = start + while (i < end) { + var firstByte = buf[i] + var codePoint = null + var bytesPerSequence = (firstByte > 0xEF) ? 4 + : (firstByte > 0xDF) ? 3 + : (firstByte > 0xBF) ? 2 + : 1 -// ISO/IEC 14496-12:2012 - 8.8.8 Track Run Box -// Note: the 'trun' box has a direct relation to the 'tfhd' box for defaults. -// These defaults are not set explicitly here, but are left to resolve for the user. -ISOBox.prototype._boxProcessors['trun'] = function() { - this._procFullBox(); - this._procField('sample_count', 'uint', 32); - if (this.flags & 0x1) this._procField('data_offset', 'int', 32); - if (this.flags & 0x4) this._procField('first_sample_flags', 'uint', 32); - this._procEntries('samples', this.sample_count, function(sample) { - if (this.flags & 0x100) this._procEntryField(sample, 'sample_duration', 'uint', 32); - if (this.flags & 0x200) this._procEntryField(sample, 'sample_size', 'uint', 32); - if (this.flags & 0x400) this._procEntryField(sample, 'sample_flags', 'uint', 32); - if (this.flags & 0x800) this._procEntryField(sample, 'sample_composition_time_offset', (this.version === 1) ? 'int' : 'uint', 32); - }); -}; + if (i + bytesPerSequence <= end) { + var secondByte, thirdByte, fourthByte, tempCodePoint -// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box -ISOBox.prototype._boxProcessors['url '] = ISOBox.prototype._boxProcessors['urn '] = function() { - this._procFullBox(); - if (this.type === 'urn ') { - this._procField('name', 'string', -1); - } - this._procField('location', 'string', -1); -}; + switch (bytesPerSequence) { + case 1: + if (firstByte < 0x80) { + codePoint = firstByte + } + break + case 2: + secondByte = buf[i + 1] + if ((secondByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) + if (tempCodePoint > 0x7F) { + codePoint = tempCodePoint + } + } + break + case 3: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) + if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { + codePoint = tempCodePoint + } + } + break + case 4: + secondByte = buf[i + 1] + thirdByte = buf[i + 2] + fourthByte = buf[i + 3] + if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { + tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) + if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { + codePoint = tempCodePoint + } + } + } + } -// ISO/IEC 14496-30:2014 - WebVTT Source Label Box -ISOBox.prototype._boxProcessors['vlab'] = function() { - this._procField('source_label', 'utf8'); -}; + if (codePoint === null) { + // we did not generate a valid codePoint so insert a + // replacement char (U+FFFD) and advance only 1 byte + codePoint = 0xFFFD + bytesPerSequence = 1 + } else if (codePoint > 0xFFFF) { + // encode to utf16 (surrogate pair dance) + codePoint -= 0x10000 + res.push(codePoint >>> 10 & 0x3FF | 0xD800) + codePoint = 0xDC00 | codePoint & 0x3FF + } -// ISO/IEC 14496-12:2012 - 8.4.5.2 Video Media Header Box -ISOBox.prototype._boxProcessors['vmhd'] = function() { - this._procFullBox(); - this._procField('graphicsmode', 'uint', 16); - this._procFieldArray('opcolor', 3, 'uint', 16); -}; + res.push(codePoint) + i += bytesPerSequence + } -// ISO/IEC 14496-30:2014 - WebVTT Configuration Box -ISOBox.prototype._boxProcessors['vttC'] = function() { - this._procField('config', 'utf8'); -}; + return decodeCodePointsArray(res) +} -// ISO/IEC 14496-30:2014 - WebVTT Empty Sample Box -ISOBox.prototype._boxProcessors['vtte'] = function() { - // Nothing should happen here. -}; +// Based on http://stackoverflow.com/a/22747272/680742, the browser with +// the lowest limit is Chrome, with 0x10000 args. +// We go 1 magnitude less, for safety +var MAX_ARGUMENTS_LENGTH = 0x1000 -},{}],7:[function(_dereq_,module,exports){ -'use strict'; +function decodeCodePointsArray (codePoints) { + var len = codePoints.length + if (len <= MAX_ARGUMENTS_LENGTH) { + return String.fromCharCode.apply(String, codePoints) // avoid extra slice() + } -var isArray = Array.isArray; -var keyList = Object.keys; -var hasProp = Object.prototype.hasOwnProperty; + // Decode in chunks to avoid "call stack size exceeded". + var res = '' + var i = 0 + while (i < len) { + res += String.fromCharCode.apply( + String, + codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) + ) + } + return res +} -module.exports = function equal(a, b) { - if (a === b) return true; +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) - var arrA = isArray(a) - , arrB = isArray(b) - , i - , length - , key; - - if (arrA && arrB) { - length = a.length; - if (length != b.length) return false; - for (i = 0; i < length; i++) - if (!equal(a[i], b[i])) return false; - return true; + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i] & 0x7F) } + return ret +} - if (arrA != arrB) return false; +function latin1Slice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) - var dateA = a instanceof Date - , dateB = b instanceof Date; - if (dateA != dateB) return false; - if (dateA && dateB) return a.getTime() == b.getTime(); + for (var i = start; i < end; ++i) { + ret += String.fromCharCode(buf[i]) + } + return ret +} - var regexpA = a instanceof RegExp - , regexpB = b instanceof RegExp; - if (regexpA != regexpB) return false; - if (regexpA && regexpB) return a.toString() == b.toString(); +function hexSlice (buf, start, end) { + var len = buf.length - if (a instanceof Object && b instanceof Object) { - var keys = keyList(a); - length = keys.length; + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len - if (length !== keyList(b).length) - return false; + var out = '' + for (var i = start; i < end; ++i) { + out += toHex(buf[i]) + } + return out +} - for (i = 0; i < length; i++) - if (!hasProp.call(b, keys[i])) return false; +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + (bytes[i + 1] * 256)) + } + return res +} - for (i = 0; i < length; i++) { - key = keys[i]; - if (!equal(a[key], b[key])) return false; - } +Buffer.prototype.slice = function slice (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end - return true; + if (start < 0) { + start += len + if (start < 0) start = 0 + } else if (start > len) { + start = len } - return false; -}; + if (end < 0) { + end += len + if (end < 0) end = 0 + } else if (end > len) { + end = len + } -},{}],8:[function(_dereq_,module,exports){ -var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -;(function (exports) { - 'use strict'; - - var Arr = (typeof Uint8Array !== 'undefined') - ? Uint8Array - : Array - - var PLUS = '+'.charCodeAt(0) - var SLASH = '/'.charCodeAt(0) - var NUMBER = '0'.charCodeAt(0) - var LOWER = 'a'.charCodeAt(0) - var UPPER = 'A'.charCodeAt(0) - var PLUS_URL_SAFE = '-'.charCodeAt(0) - var SLASH_URL_SAFE = '_'.charCodeAt(0) - - function decode (elt) { - var code = elt.charCodeAt(0) - if (code === PLUS || - code === PLUS_URL_SAFE) - return 62 // '+' - if (code === SLASH || - code === SLASH_URL_SAFE) - return 63 // '/' - if (code < NUMBER) - return -1 //no match - if (code < NUMBER + 10) - return code - NUMBER + 26 + 26 - if (code < UPPER + 26) - return code - UPPER - if (code < LOWER + 26) - return code - LOWER + 26 - } - - function b64ToByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - - if (b64.length % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - var len = b64.length - placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(b64.length * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? b64.length - 4 : b64.length - - var L = 0 - - function push (v) { - arr[L++] = v - } - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) - push((tmp & 0xFF0000) >> 16) - push((tmp & 0xFF00) >> 8) - push(tmp & 0xFF) - } - - if (placeHolders === 2) { - tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) - push(tmp & 0xFF) - } else if (placeHolders === 1) { - tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) - push((tmp >> 8) & 0xFF) - push(tmp & 0xFF) - } - - return arr - } - - function uint8ToBase64 (uint8) { - var i, - extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes - output = "", - temp, length - - function encode (num) { - return lookup.charAt(num) - } - - function tripletToBase64 (num) { - return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) - } - - // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output += tripletToBase64(temp) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - switch (extraBytes) { - case 1: - temp = uint8[uint8.length - 1] - output += encode(temp >> 2) - output += encode((temp << 4) & 0x3F) - output += '==' - break - case 2: - temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) - output += encode(temp >> 10) - output += encode((temp >> 4) & 0x3F) - output += encode((temp << 2) & 0x3F) - output += '=' - break - } - - return output - } - - exports.toByteArray = b64ToByteArray - exports.fromByteArray = uint8ToBase64 -}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) - -},{}],9:[function(_dereq_,module,exports){ + if (end < start) end = start -},{}],10:[function(_dereq_,module,exports){ -(function (global){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -/* eslint-disable no-proto */ - -'use strict' - -var base64 = _dereq_(8) -var ieee754 = _dereq_(14) -var isArray = _dereq_(11) - -exports.Buffer = Buffer -exports.SlowBuffer = SlowBuffer -exports.INSPECT_MAX_BYTES = 50 -Buffer.poolSize = 8192 // not used by this implementation - -var rootParent = {} - -/** - * If `Buffer.TYPED_ARRAY_SUPPORT`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (most compatible, even IE6) - * - * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, - * Opera 11.6+, iOS 4.2+. - * - * Due to various browser bugs, sometimes the Object implementation will be used even - * when the browser supports typed arrays. - * - * Note: - * - * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances, - * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. - * - * - Safari 5-7 lacks support for changing the `Object.prototype.constructor` property - * on objects. - * - * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. - * - * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of - * incorrect length in some situations. + var newBuf = this.subarray(start, end) + // Return an augmented `Uint8Array` instance + newBuf.__proto__ = Buffer.prototype + return newBuf +} - * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they - * get the Object implementation, which is slower but behaves correctly. +/* + * Need to make sure that buffer isn't trying to write out of bounds. */ -Buffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined - ? global.TYPED_ARRAY_SUPPORT - : typedArraySupport() - -function typedArraySupport () { - function Bar () {} - try { - var arr = new Uint8Array(1) - arr.foo = function () { return 42 } - arr.constructor = Bar - return arr.foo() === 42 && // typed array instances can be augmented - arr.constructor === Bar && // constructor can be set - typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` - arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` - } catch (e) { - return false - } +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') + if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') } -function kMaxLength () { - return Buffer.TYPED_ARRAY_SUPPORT - ? 0x7fffffff - : 0x3fffffff -} +Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) -/** - * Class: Buffer - * ============= - * - * The Buffer constructor returns instances of `Uint8Array` that are augmented - * with function properties for all the node `Buffer` API functions. We use - * `Uint8Array` so that square bracket notation works as expected -- it returns - * a single octet. - * - * By augmenting the instances, we can avoid modifying the `Uint8Array` - * prototype. - */ -function Buffer (arg) { - if (!(this instanceof Buffer)) { - // Avoid going through an ArgumentsAdaptorTrampoline in the common case. - if (arguments.length > 1) return new Buffer(arg, arguments[1]) - return new Buffer(arg) + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul } - if (!Buffer.TYPED_ARRAY_SUPPORT) { - this.length = 0 - this.parent = undefined - } + return val +} - // Common case. - if (typeof arg === 'number') { - return fromNumber(this, arg) +Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) { + checkOffset(offset, byteLength, this.length) } - // Slightly less common case. - if (typeof arg === 'string') { - return fromString(this, arg, arguments.length > 1 ? arguments[1] : 'utf8') + var val = this[offset + --byteLength] + var mul = 1 + while (byteLength > 0 && (mul *= 0x100)) { + val += this[offset + --byteLength] * mul } - // Unusual. - return fromObject(this, arg) + return val } -function fromNumber (that, length) { - that = allocate(that, length < 0 ? 0 : checked(length) | 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) { - for (var i = 0; i < length; i++) { - that[i] = 0 - } - } - return that +Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 1, this.length) + return this[offset] +} + +Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) } -function fromString (that, string, encoding) { - if (typeof encoding !== 'string' || encoding === '') encoding = 'utf8' +Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} - // Assumption: byteLength() return value is always < kMaxLength. - var length = byteLength(string, encoding) | 0 - that = allocate(that, length) +Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 4, this.length) - that.write(string, encoding) - return that + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) } -function fromObject (that, object) { - if (Buffer.isBuffer(object)) return fromBuffer(that, object) +Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 4, this.length) - if (isArray(object)) return fromArray(that, object) + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} - if (object == null) { - throw new TypeError('must start with number, buffer, array or string') - } +Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) - if (typeof ArrayBuffer !== 'undefined') { - if (object.buffer instanceof ArrayBuffer) { - return fromTypedArray(that, object) - } - if (object instanceof ArrayBuffer) { - return fromArrayBuffer(that, object) - } + var val = this[offset] + var mul = 1 + var i = 0 + while (++i < byteLength && (mul *= 0x100)) { + val += this[offset + i] * mul } + mul *= 0x80 - if (object.length) return fromArrayLike(that, object) + if (val >= mul) val -= Math.pow(2, 8 * byteLength) - return fromJsonObject(that, object) + return val } -function fromBuffer (that, buffer) { - var length = checked(buffer.length) | 0 - that = allocate(that, length) - buffer.copy(that, 0, 0, length) - return that -} +Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) checkOffset(offset, byteLength, this.length) -function fromArray (that, array) { - var length = checked(array.length) | 0 - that = allocate(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 + var i = byteLength + var mul = 1 + var val = this[offset + --i] + while (i > 0 && (mul *= 0x100)) { + val += this[offset + --i] * mul } - return that + mul *= 0x80 + + if (val >= mul) val -= Math.pow(2, 8 * byteLength) + + return val } -// Duplicate of fromArray() to keep fromArray() monomorphic. -function fromTypedArray (that, array) { - var length = checked(array.length) | 0 - that = allocate(that, length) - // Truncating the elements is probably not what people expect from typed - // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior - // of the old Buffer constructor. - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that +Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) return (this[offset]) + return ((0xff - this[offset] + 1) * -1) } -function fromArrayBuffer (that, array) { - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - array.byteLength - that = Buffer._augment(new Uint8Array(array)) - } else { - // Fallback: Return an object instance of the Buffer class - that = fromTypedArray(that, new Uint8Array(array)) - } - return that +Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val } -function fromArrayLike (that, array) { - var length = checked(array.length) | 0 - that = allocate(that, length) - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that +Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val } -// Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object. -// Returns a zero-length buffer for inputs that don't conform to the spec. -function fromJsonObject (that, object) { - var array - var length = 0 +Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 4, this.length) - if (object.type === 'Buffer' && isArray(object.data)) { - array = object.data - length = checked(array.length) | 0 - } - that = allocate(that, length) + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} - for (var i = 0; i < length; i += 1) { - that[i] = array[i] & 255 - } - return that +Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 4, this.length) + + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) } -if (Buffer.TYPED_ARRAY_SUPPORT) { - Buffer.prototype.__proto__ = Uint8Array.prototype - Buffer.__proto__ = Uint8Array -} else { - // pre-set for values that may exist in the future - Buffer.prototype.length = undefined - Buffer.prototype.parent = undefined +Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) } -function allocate (that, length) { - if (Buffer.TYPED_ARRAY_SUPPORT) { - // Return an augmented `Uint8Array` instance, for best performance - that = Buffer._augment(new Uint8Array(length)) - that.__proto__ = Buffer.prototype - } else { - // Fallback: Return an object instance of the Buffer class - that.length = length - that._isBuffer = true - } +Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} - var fromPool = length !== 0 && length <= Buffer.poolSize >>> 1 - if (fromPool) that.parent = rootParent +Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} - return that +Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { + offset = offset >>> 0 + if (!noAssert) checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) } -function checked (length) { - // Note: cannot use `length < kMaxLength` here because that fails when - // length is NaN (which is otherwise coerced to zero.) - if (length >= kMaxLength()) { - throw new RangeError('Attempt to allocate Buffer larger than maximum ' + - 'size: 0x' + kMaxLength().toString(16) + ' bytes') - } - return length | 0 +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') + if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') + if (offset + ext > buf.length) throw new RangeError('Index out of range') } -function SlowBuffer (subject, encoding) { - if (!(this instanceof SlowBuffer)) return new SlowBuffer(subject, encoding) +Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) + } - var buf = new Buffer(subject, encoding) - delete buf.parent - return buf -} + var mul = 1 + var i = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } -Buffer.isBuffer = function isBuffer (b) { - return !!(b != null && b._isBuffer) + return offset + byteLength } -Buffer.compare = function compare (a, b) { - if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { - throw new TypeError('Arguments must be Buffers') +Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + byteLength = byteLength >>> 0 + if (!noAssert) { + var maxBytes = Math.pow(2, 8 * byteLength) - 1 + checkInt(this, value, offset, byteLength, maxBytes, 0) } - if (a === b) return 0 + var i = byteLength - 1 + var mul = 1 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + this[offset + i] = (value / mul) & 0xFF + } - var x = a.length - var y = b.length + return offset + byteLength +} - var i = 0 - var len = Math.min(x, y) - while (i < len) { - if (a[i] !== b[i]) break +Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) + this[offset] = (value & 0xff) + return offset + 1 +} - ++i - } +Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + return offset + 2 +} - if (i !== len) { - x = a[i] - y = b[i] - } +Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + return offset + 2 +} - if (x < y) return -1 - if (y < x) return 1 - return 0 +Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = (value & 0xff) + return offset + 4 } -Buffer.isEncoding = function isEncoding (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'binary': - case 'base64': - case 'raw': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } +Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + return offset + 4 } -Buffer.concat = function concat (list, length) { - if (!isArray(list)) throw new TypeError('list argument must be an Array of Buffers.') +Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) { + var limit = Math.pow(2, (8 * byteLength) - 1) - if (list.length === 0) { - return new Buffer(0) + checkInt(this, value, offset, byteLength, limit - 1, -limit) } - var i - if (length === undefined) { - length = 0 - for (i = 0; i < list.length; i++) { - length += list[i].length + var i = 0 + var mul = 1 + var sub = 0 + this[offset] = value & 0xFF + while (++i < byteLength && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) { + sub = 1 } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } - var buf = new Buffer(length) - var pos = 0 - for (i = 0; i < list.length; i++) { - var item = list[i] - item.copy(buf, pos) - pos += item.length - } - return buf + return offset + byteLength } -function byteLength (string, encoding) { - if (typeof string !== 'string') string = '' + string +Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) { + var limit = Math.pow(2, (8 * byteLength) - 1) - var len = string.length - if (len === 0) return 0 + checkInt(this, value, offset, byteLength, limit - 1, -limit) + } - // Use a for loop to avoid recursion - var loweredCase = false - for (;;) { - switch (encoding) { - case 'ascii': - case 'binary': - // Deprecated - case 'raw': - case 'raws': - return len - case 'utf8': - case 'utf-8': - return utf8ToBytes(string).length - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return len * 2 - case 'hex': - return len >>> 1 - case 'base64': - return base64ToBytes(string).length - default: - if (loweredCase) return utf8ToBytes(string).length // assume utf8 - encoding = ('' + encoding).toLowerCase() - loweredCase = true + var i = byteLength - 1 + var mul = 1 + var sub = 0 + this[offset + i] = value & 0xFF + while (--i >= 0 && (mul *= 0x100)) { + if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) { + sub = 1 } + this[offset + i] = ((value / mul) >> 0) - sub & 0xFF } -} -Buffer.byteLength = byteLength - -function slowToString (encoding, start, end) { - var loweredCase = false - start = start | 0 - end = end === undefined || end === Infinity ? this.length : end | 0 - - if (!encoding) encoding = 'utf8' - if (start < 0) start = 0 - if (end > this.length) end = this.length - if (end <= start) return '' + return offset + byteLength +} - while (true) { - switch (encoding) { - case 'hex': - return hexSlice(this, start, end) +Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) + if (value < 0) value = 0xff + value + 1 + this[offset] = (value & 0xff) + return offset + 1 +} - case 'utf8': - case 'utf-8': - return utf8Slice(this, start, end) +Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + return offset + 2 +} - case 'ascii': - return asciiSlice(this, start, end) +Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) + this[offset] = (value >>> 8) + this[offset + 1] = (value & 0xff) + return offset + 2 +} - case 'binary': - return binarySlice(this, start, end) +Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + this[offset] = (value & 0xff) + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + return offset + 4 +} - case 'base64': - return base64Slice(this, start, end) +Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = (value & 0xff) + return offset + 4 +} - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return utf16leSlice(this, start, end) +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (offset + ext > buf.length) throw new RangeError('Index out of range') + if (offset < 0) throw new RangeError('Index out of range') +} - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = (encoding + '').toLowerCase() - loweredCase = true - } +function writeFloat (buf, value, offset, littleEndian, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) { + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) } + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 } -Buffer.prototype.toString = function toString () { - var length = this.length | 0 - if (length === 0) return '' - if (arguments.length === 0) return utf8Slice(this, 0, length) - return slowToString.apply(this, arguments) +Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) } -Buffer.prototype.equals = function equals (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return true - return Buffer.compare(this, b) === 0 +Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) } -Buffer.prototype.inspect = function inspect () { - var str = '' - var max = exports.INSPECT_MAX_BYTES - if (this.length > 0) { - str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') - if (this.length > max) str += ' ... ' +function writeDouble (buf, value, offset, littleEndian, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) { + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) } - return '' + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 } -Buffer.prototype.compare = function compare (b) { - if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') - if (this === b) return 0 - return Buffer.compare(this, b) +Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) } -Buffer.prototype.indexOf = function indexOf (val, byteOffset) { - if (byteOffset > 0x7fffffff) byteOffset = 0x7fffffff - else if (byteOffset < -0x80000000) byteOffset = -0x80000000 - byteOffset >>= 0 +Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} - if (this.length === 0) return -1 - if (byteOffset >= this.length) return -1 +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function copy (target, targetStart, start, end) { + if (!Buffer.isBuffer(target)) throw new TypeError('argument should be a Buffer') + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (targetStart >= target.length) targetStart = target.length + if (!targetStart) targetStart = 0 + if (end > 0 && end < start) end = start - // Negative offsets start from the end of the buffer - if (byteOffset < 0) byteOffset = Math.max(this.length + byteOffset, 0) + // Copy 0 bytes; we're done + if (end === start) return 0 + if (target.length === 0 || this.length === 0) return 0 - if (typeof val === 'string') { - if (val.length === 0) return -1 // special case: looking for empty string always fails - return String.prototype.indexOf.call(this, val, byteOffset) + // Fatal error conditions + if (targetStart < 0) { + throw new RangeError('targetStart out of bounds') } - if (Buffer.isBuffer(val)) { - return arrayIndexOf(this, val, byteOffset) + if (start < 0 || start >= this.length) throw new RangeError('Index out of range') + if (end < 0) throw new RangeError('sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) end = this.length + if (target.length - targetStart < end - start) { + end = target.length - targetStart + start } - if (typeof val === 'number') { - if (Buffer.TYPED_ARRAY_SUPPORT && Uint8Array.prototype.indexOf === 'function') { - return Uint8Array.prototype.indexOf.call(this, val, byteOffset) + + var len = end - start + + if (this === target && typeof Uint8Array.prototype.copyWithin === 'function') { + // Use built-in when available, missing from IE11 + this.copyWithin(targetStart, start, end) + } else if (this === target && start < targetStart && targetStart < end) { + // descending copy from end + for (var i = len - 1; i >= 0; --i) { + target[i + targetStart] = this[i + start] } - return arrayIndexOf(this, [ val ], byteOffset) + } else { + Uint8Array.prototype.set.call( + target, + this.subarray(start, end), + targetStart + ) } - function arrayIndexOf (arr, val, byteOffset) { - var foundIndex = -1 - for (var i = 0; byteOffset + i < arr.length; i++) { - if (arr[byteOffset + i] === val[foundIndex === -1 ? 0 : i - foundIndex]) { - if (foundIndex === -1) foundIndex = i - if (i - foundIndex + 1 === val.length) return byteOffset + foundIndex - } else { - foundIndex = -1 + return len +} + +// Usage: +// buffer.fill(number[, offset[, end]]) +// buffer.fill(buffer[, offset[, end]]) +// buffer.fill(string[, offset[, end]][, encoding]) +Buffer.prototype.fill = function fill (val, start, end, encoding) { + // Handle string cases: + if (typeof val === 'string') { + if (typeof start === 'string') { + encoding = start + start = 0 + end = this.length + } else if (typeof end === 'string') { + encoding = end + end = this.length + } + if (encoding !== undefined && typeof encoding !== 'string') { + throw new TypeError('encoding must be a string') + } + if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) { + throw new TypeError('Unknown encoding: ' + encoding) + } + if (val.length === 1) { + var code = val.charCodeAt(0) + if ((encoding === 'utf8' && code < 128) || + encoding === 'latin1') { + // Fast path: If `val` fits into a single byte, use that numeric value. + val = code } } - return -1 + } else if (typeof val === 'number') { + val = val & 255 } - throw new TypeError('val must be string, number or Buffer') -} + // Invalid ranges are not set to a default, so can range check early. + if (start < 0 || this.length < start || this.length < end) { + throw new RangeError('Out of range index') + } -// `get` is deprecated -Buffer.prototype.get = function get (offset) { - console.log('.get() is deprecated. Access using array indexes instead.') - return this.readUInt8(offset) -} + if (end <= start) { + return this + } -// `set` is deprecated -Buffer.prototype.set = function set (v, offset) { - console.log('.set() is deprecated. Access using array indexes instead.') - return this.writeUInt8(v, offset) -} + start = start >>> 0 + end = end === undefined ? this.length : end >>> 0 -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining + if (!val) val = 0 + + var i + if (typeof val === 'number') { + for (i = start; i < end; ++i) { + this[i] = val + } } else { - length = Number(length) - if (length > remaining) { - length = remaining + var bytes = Buffer.isBuffer(val) + ? val + : Buffer.from(val, encoding) + var len = bytes.length + if (len === 0) { + throw new TypeError('The value "' + val + + '" is invalid for argument "value"') + } + for (i = 0; i < end - start; ++i) { + this[i + start] = bytes[i % len] } } - // must be an even number of digits - var strLen = string.length - if (strLen % 2 !== 0) throw new Error('Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; i++) { - var parsed = parseInt(string.substr(i * 2, 2), 16) - if (isNaN(parsed)) throw new Error('Invalid hex string') - buf[offset + i] = parsed - } - return i + return this } -function utf8Write (buf, string, offset, length) { - return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) -} +// HELPER FUNCTIONS +// ================ -function asciiWrite (buf, string, offset, length) { - return blitBuffer(asciiToBytes(string), buf, offset, length) -} +var INVALID_BASE64_RE = /[^+/0-9A-Za-z-_]/g -function binaryWrite (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) +function base64clean (str) { + // Node takes equal signs as end of the Base64 encoding + str = str.split('=')[0] + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = str.trim().replace(INVALID_BASE64_RE, '') + // Node converts strings with length < 2 to '' + if (str.length < 2) return '' + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str } -function base64Write (buf, string, offset, length) { - return blitBuffer(base64ToBytes(string), buf, offset, length) +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) } -function ucs2Write (buf, string, offset, length) { - return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) -} +function utf8ToBytes (string, units) { + units = units || Infinity + var codePoint + var length = string.length + var leadSurrogate = null + var bytes = [] -Buffer.prototype.write = function write (string, offset, length, encoding) { - // Buffer#write(string) - if (offset === undefined) { - encoding = 'utf8' - length = this.length - offset = 0 - // Buffer#write(string, encoding) - } else if (length === undefined && typeof offset === 'string') { - encoding = offset - length = this.length - offset = 0 - // Buffer#write(string, offset[, length][, encoding]) - } else if (isFinite(offset)) { - offset = offset | 0 - if (isFinite(length)) { - length = length | 0 - if (encoding === undefined) encoding = 'utf8' - } else { - encoding = length - length = undefined - } - // legacy write(string, encoding, offset, length) - remove in v0.13 - } else { - var swap = encoding - encoding = offset - offset = length | 0 - length = swap - } - - var remaining = this.length - offset - if (length === undefined || length > remaining) length = remaining - - if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) { - throw new RangeError('attempt to write outside buffer bounds') - } - - if (!encoding) encoding = 'utf8' + for (var i = 0; i < length; ++i) { + codePoint = string.charCodeAt(i) - var loweredCase = false - for (;;) { - switch (encoding) { - case 'hex': - return hexWrite(this, string, offset, length) + // is surrogate component + if (codePoint > 0xD7FF && codePoint < 0xE000) { + // last char was a lead + if (!leadSurrogate) { + // no lead yet + if (codePoint > 0xDBFF) { + // unexpected trail + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } else if (i + 1 === length) { + // unpaired lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + continue + } - case 'utf8': - case 'utf-8': - return utf8Write(this, string, offset, length) + // valid lead + leadSurrogate = codePoint - case 'ascii': - return asciiWrite(this, string, offset, length) + continue + } - case 'binary': - return binaryWrite(this, string, offset, length) + // 2 leads in a row + if (codePoint < 0xDC00) { + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + leadSurrogate = codePoint + continue + } - case 'base64': - // Warning: maxLength not taken into account in base64Write - return base64Write(this, string, offset, length) + // valid surrogate pair + codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 + } else if (leadSurrogate) { + // valid bmp char, but last char was a lead + if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + } - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return ucs2Write(this, string, offset, length) + leadSurrogate = null - default: - if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding) - encoding = ('' + encoding).toLowerCase() - loweredCase = true + // encode utf8 + if (codePoint < 0x80) { + if ((units -= 1) < 0) break + bytes.push(codePoint) + } else if (codePoint < 0x800) { + if ((units -= 2) < 0) break + bytes.push( + codePoint >> 0x6 | 0xC0, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x10000) { + if ((units -= 3) < 0) break + bytes.push( + codePoint >> 0xC | 0xE0, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else if (codePoint < 0x110000) { + if ((units -= 4) < 0) break + bytes.push( + codePoint >> 0x12 | 0xF0, + codePoint >> 0xC & 0x3F | 0x80, + codePoint >> 0x6 & 0x3F | 0x80, + codePoint & 0x3F | 0x80 + ) + } else { + throw new Error('Invalid code point') } } -} -Buffer.prototype.toJSON = function toJSON () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } + return bytes } -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) } + return byteArray } -function utf8Slice (buf, start, end) { - end = Math.min(buf.length, end) - var res = [] - - var i = start - while (i < end) { - var firstByte = buf[i] - var codePoint = null - var bytesPerSequence = (firstByte > 0xEF) ? 4 - : (firstByte > 0xDF) ? 3 - : (firstByte > 0xBF) ? 2 - : 1 +function utf16leToBytes (str, units) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; ++i) { + if ((units -= 2) < 0) break - if (i + bytesPerSequence <= end) { - var secondByte, thirdByte, fourthByte, tempCodePoint + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } - switch (bytesPerSequence) { - case 1: - if (firstByte < 0x80) { - codePoint = firstByte - } - break - case 2: - secondByte = buf[i + 1] - if ((secondByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F) - if (tempCodePoint > 0x7F) { - codePoint = tempCodePoint - } - } - break - case 3: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F) - if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) { - codePoint = tempCodePoint - } - } - break - case 4: - secondByte = buf[i + 1] - thirdByte = buf[i + 2] - fourthByte = buf[i + 3] - if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) { - tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F) - if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) { - codePoint = tempCodePoint - } - } - } - } + return byteArray +} - if (codePoint === null) { - // we did not generate a valid codePoint so insert a - // replacement char (U+FFFD) and advance only 1 byte - codePoint = 0xFFFD - bytesPerSequence = 1 - } else if (codePoint > 0xFFFF) { - // encode to utf16 (surrogate pair dance) - codePoint -= 0x10000 - res.push(codePoint >>> 10 & 0x3FF | 0xD800) - codePoint = 0xDC00 | codePoint & 0x3FF - } +function base64ToBytes (str) { + return base64.toByteArray(base64clean(str)) +} - res.push(codePoint) - i += bytesPerSequence +function blitBuffer (src, dst, offset, length) { + for (var i = 0; i < length; ++i) { + if ((i + offset >= dst.length) || (i >= src.length)) break + dst[i + offset] = src[i] } + return i +} - return decodeCodePointsArray(res) +// ArrayBuffer or Uint8Array objects from other contexts (i.e. iframes) do not pass +// the `instanceof` check but they should be treated as of that type. +// See: https://github.com/feross/buffer/issues/166 +function isInstance (obj, type) { + return obj instanceof type || + (obj != null && obj.constructor != null && obj.constructor.name != null && + obj.constructor.name === type.name) +} +function numberIsNaN (obj) { + // For IE11 support + return obj !== obj // eslint-disable-line no-self-compare } -// Based on http://stackoverflow.com/a/22747272/680742, the browser with -// the lowest limit is Chrome, with 0x10000 args. -// We go 1 magnitude less, for safety -var MAX_ARGUMENTS_LENGTH = 0x1000 +},{"12":12,"6":6}],9:[function(_dereq_,module,exports){ +/*! codem-isoboxer v0.3.6 https://github.com/madebyhiro/codem-isoboxer/blob/master/LICENSE.txt */ +var ISOBoxer = {}; -function decodeCodePointsArray (codePoints) { - var len = codePoints.length - if (len <= MAX_ARGUMENTS_LENGTH) { - return String.fromCharCode.apply(String, codePoints) // avoid extra slice() - } +ISOBoxer.parseBuffer = function(arrayBuffer) { + return new ISOFile(arrayBuffer).parse(); +}; - // Decode in chunks to avoid "call stack size exceeded". - var res = '' - var i = 0 - while (i < len) { - res += String.fromCharCode.apply( - String, - codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH) - ) +ISOBoxer.addBoxProcessor = function(type, parser) { + if (typeof type !== 'string' || typeof parser !== 'function') { + return; } - return res -} + ISOBox.prototype._boxProcessors[type] = parser; +}; -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) +ISOBoxer.createFile = function() { + return new ISOFile(); +}; - for (var i = start; i < end; i++) { - ret += String.fromCharCode(buf[i] & 0x7F) +// See ISOBoxer.append() for 'pos' parameter syntax +ISOBoxer.createBox = function(type, parent, pos) { + var newBox = ISOBox.create(type); + if (parent) { + parent.append(newBox, pos); } - return ret -} + return newBox; +}; -function binarySlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) +// See ISOBoxer.append() for 'pos' parameter syntax +ISOBoxer.createFullBox = function(type, parent, pos) { + var newBox = ISOBoxer.createBox(type, parent, pos); + newBox.version = 0; + newBox.flags = 0; + return newBox; +}; - for (var i = start; i < end; i++) { - ret += String.fromCharCode(buf[i]) +ISOBoxer.Utils = {}; +ISOBoxer.Utils.dataViewToString = function(dataView, encoding) { + var impliedEncoding = encoding || 'utf-8'; + if (typeof TextDecoder !== 'undefined') { + return new TextDecoder(impliedEncoding).decode(dataView); } - return ret -} - -function hexSlice (buf, start, end) { - var len = buf.length + var a = []; + var i = 0; - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len + if (impliedEncoding === 'utf-8') { + /* The following algorithm is essentially a rewrite of the UTF8.decode at + http://bannister.us/weblog/2007/simple-base64-encodedecode-javascript/ + */ - var out = '' - for (var i = start; i < end; i++) { - out += toHex(buf[i]) + while (i < dataView.byteLength) { + var c = dataView.getUint8(i++); + if (c < 0x80) { + // 1-byte character (7 bits) + } else if (c < 0xe0) { + // 2-byte character (11 bits) + c = (c & 0x1f) << 6; + c |= (dataView.getUint8(i++) & 0x3f); + } else if (c < 0xf0) { + // 3-byte character (16 bits) + c = (c & 0xf) << 12; + c |= (dataView.getUint8(i++) & 0x3f) << 6; + c |= (dataView.getUint8(i++) & 0x3f); + } else { + // 4-byte character (21 bits) + c = (c & 0x7) << 18; + c |= (dataView.getUint8(i++) & 0x3f) << 12; + c |= (dataView.getUint8(i++) & 0x3f) << 6; + c |= (dataView.getUint8(i++) & 0x3f); + } + a.push(String.fromCharCode(c)); + } + } else { // Just map byte-by-byte (probably wrong) + while (i < dataView.byteLength) { + a.push(String.fromCharCode(dataView.getUint8(i++))); + } } - return out -} + return a.join(''); +}; -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) +ISOBoxer.Utils.utf8ToByteArray = function(string) { + // Only UTF-8 encoding is supported by TextEncoder + var u, i; + if (typeof TextEncoder !== 'undefined') { + u = new TextEncoder().encode(string); + } else { + u = []; + for (i = 0; i < string.length; ++i) { + var c = string.charCodeAt(i); + if (c < 0x80) { + u.push(c); + } else if (c < 0x800) { + u.push(0xC0 | (c >> 6)); + u.push(0x80 | (63 & c)); + } else if (c < 0x10000) { + u.push(0xE0 | (c >> 12)); + u.push(0x80 | (63 & (c >> 6))); + u.push(0x80 | (63 & c)); + } else { + u.push(0xF0 | (c >> 18)); + u.push(0x80 | (63 & (c >> 12))); + u.push(0x80 | (63 & (c >> 6))); + u.push(0x80 | (63 & c)); + } + } } - return res -} + return u; +}; -Buffer.prototype.slice = function slice (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end +// Method to append a box in the list of child boxes +// The 'pos' parameter can be either: +// - (number) a position index at which to insert the new box +// - (string) the type of the box after which to insert the new box +// - (object) the box after which to insert the new box +ISOBoxer.Utils.appendBox = function(parent, box, pos) { + box._offset = parent._cursor.offset; + box._root = (parent._root ? parent._root : parent); + box._raw = parent._raw; + box._parent = parent; - if (start < 0) { - start += len - if (start < 0) start = 0 - } else if (start > len) { - start = len + if (pos === -1) { + // The new box is a sub-box of the parent but not added in boxes array, + // for example when the new box is set as an entry (see dref and stsd for example) + return; } - if (end < 0) { - end += len - if (end < 0) end = 0 - } else if (end > len) { - end = len + if (pos === undefined || pos === null) { + parent.boxes.push(box); + return; } - if (end < start) end = start + var index = -1, + type; - var newBuf - if (Buffer.TYPED_ARRAY_SUPPORT) { - newBuf = Buffer._augment(this.subarray(start, end)) + if (typeof pos === "number") { + index = pos; } else { - var sliceLen = end - start - newBuf = new Buffer(sliceLen, undefined) - for (var i = 0; i < sliceLen; i++) { - newBuf[i] = this[i + start] + if (typeof pos === "string") { + type = pos; + } else if (typeof pos === "object" && pos.type) { + type = pos.type; + } else { + parent.boxes.push(box); + return; } - } - - if (newBuf.length) newBuf.parent = this.parent || this - return newBuf -} + for (var i = 0; i < parent.boxes.length; i++) { + if (type === parent.boxes[i].type) { + index = i + 1; + break; + } + } + } + parent.boxes.splice(index, 0, box); +}; -/* - * Need to make sure that buffer isn't trying to write out of bounds. - */ -function checkOffset (offset, ext, length) { - if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') - if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') +if (typeof exports !== 'undefined') { + exports.parseBuffer = ISOBoxer.parseBuffer; + exports.addBoxProcessor = ISOBoxer.addBoxProcessor; + exports.createFile = ISOBoxer.createFile; + exports.createBox = ISOBoxer.createBox; + exports.createFullBox = ISOBoxer.createFullBox; + exports.Utils = ISOBoxer.Utils; } -Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) +ISOBoxer.Cursor = function(initialOffset) { + this.offset = (typeof initialOffset == 'undefined' ? 0 : initialOffset); +}; - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul +var ISOFile = function(arrayBuffer) { + this._cursor = new ISOBoxer.Cursor(); + this.boxes = []; + if (arrayBuffer) { + this._raw = new DataView(arrayBuffer); } +}; - return val -} +ISOFile.prototype.fetch = function(type) { + var result = this.fetchAll(type, true); + return (result.length ? result[0] : null); +}; -Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) { - checkOffset(offset, byteLength, this.length) +ISOFile.prototype.fetchAll = function(type, returnEarly) { + var result = []; + ISOFile._sweep.call(this, type, result, returnEarly); + return result; +}; + +ISOFile.prototype.parse = function() { + this._cursor.offset = 0; + this.boxes = []; + while (this._cursor.offset < this._raw.byteLength) { + var box = ISOBox.parse(this); + + // Box could not be parsed + if (typeof box.type === 'undefined') break; + + this.boxes.push(box); } + return this; +}; - var val = this[offset + --byteLength] - var mul = 1 - while (byteLength > 0 && (mul *= 0x100)) { - val += this[offset + --byteLength] * mul +ISOFile._sweep = function(type, result, returnEarly) { + if (this.type && this.type == type) result.push(this); + for (var box in this.boxes) { + if (result.length && returnEarly) return; + ISOFile._sweep.call(this.boxes[box], type, result, returnEarly); } +}; - return val -} +ISOFile.prototype.write = function() { -Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - return this[offset] -} + var length = 0, + i; -Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return this[offset] | (this[offset + 1] << 8) -} + for (i = 0; i < this.boxes.length; i++) { + length += this.boxes[i].getLength(false); + } -Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - return (this[offset] << 8) | this[offset + 1] -} + var bytes = new Uint8Array(length); + this._rawo = new DataView(bytes.buffer); + this.bytes = bytes; + this._cursor.offset = 0; -Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) + for (i = 0; i < this.boxes.length; i++) { + this.boxes[i].write(); + } - return ((this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16)) + - (this[offset + 3] * 0x1000000) -} + return bytes.buffer; +}; -Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) +ISOFile.prototype.append = function(box, pos) { + ISOBoxer.Utils.appendBox(this, box, pos); +}; +var ISOBox = function() { + this._cursor = new ISOBoxer.Cursor(); +}; - return (this[offset] * 0x1000000) + - ((this[offset + 1] << 16) | - (this[offset + 2] << 8) | - this[offset + 3]) -} - -Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) +ISOBox.parse = function(parent) { + var newBox = new ISOBox(); + newBox._offset = parent._cursor.offset; + newBox._root = (parent._root ? parent._root : parent); + newBox._raw = parent._raw; + newBox._parent = parent; + newBox._parseBox(); + parent._cursor.offset = newBox._raw.byteOffset + newBox._raw.byteLength; + return newBox; +}; - var val = this[offset] - var mul = 1 - var i = 0 - while (++i < byteLength && (mul *= 0x100)) { - val += this[offset + i] * mul - } - mul *= 0x80 +ISOBox.create = function(type) { + var newBox = new ISOBox(); + newBox.type = type; + newBox.boxes = []; + return newBox; +}; - if (val >= mul) val -= Math.pow(2, 8 * byteLength) +ISOBox.prototype._boxContainers = ['dinf', 'edts', 'mdia', 'meco', 'mfra', 'minf', 'moof', 'moov', 'mvex', 'stbl', 'strk', 'traf', 'trak', 'tref', 'udta', 'vttc', 'sinf', 'schi', 'encv', 'enca']; - return val -} +ISOBox.prototype._boxProcessors = {}; -Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkOffset(offset, byteLength, this.length) +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Generic read/write functions - var i = byteLength - var mul = 1 - var val = this[offset + --i] - while (i > 0 && (mul *= 0x100)) { - val += this[offset + --i] * mul +ISOBox.prototype._procField = function (name, type, size) { + if (this._parsing) { + this[name] = this._readField(type, size); } - mul *= 0x80 - - if (val >= mul) val -= Math.pow(2, 8 * byteLength) - - return val -} - -Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { - if (!noAssert) checkOffset(offset, 1, this.length) - if (!(this[offset] & 0x80)) return (this[offset]) - return ((0xff - this[offset] + 1) * -1) -} + else { + this._writeField(type, size, this[name]); + } +}; -Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset] | (this[offset + 1] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} +ISOBox.prototype._procFieldArray = function (name, length, type, size) { + var i; + if (this._parsing) { + this[name] = []; + for (i = 0; i < length; i++) { + this[name][i] = this._readField(type, size); + } + } + else { + for (i = 0; i < this[name].length; i++) { + this._writeField(type, size, this[name][i]); + } + } +}; -Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 2, this.length) - var val = this[offset + 1] | (this[offset] << 8) - return (val & 0x8000) ? val | 0xFFFF0000 : val -} +ISOBox.prototype._procFullBox = function() { + this._procField('version', 'uint', 8); + this._procField('flags', 'uint', 24); +}; -Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) +ISOBox.prototype._procEntries = function(name, length, fn) { + var i; + if (this._parsing) { + this[name] = []; + for (i = 0; i < length; i++) { + this[name].push({}); + fn.call(this, this[name][i]); + } + } + else { + for (i = 0; i < length; i++) { + fn.call(this, this[name][i]); + } + } +}; - return (this[offset]) | - (this[offset + 1] << 8) | - (this[offset + 2] << 16) | - (this[offset + 3] << 24) -} +ISOBox.prototype._procSubEntries = function(entry, name, length, fn) { + var i; + if (this._parsing) { + entry[name] = []; + for (i = 0; i < length; i++) { + entry[name].push({}); + fn.call(this, entry[name][i]); + } + } + else { + for (i = 0; i < length; i++) { + fn.call(this, entry[name][i]); + } + } +}; -Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) +ISOBox.prototype._procEntryField = function (entry, name, type, size) { + if (this._parsing) { + entry[name] = this._readField(type, size); + } + else { + this._writeField(type, size, entry[name]); + } +}; - return (this[offset] << 24) | - (this[offset + 1] << 16) | - (this[offset + 2] << 8) | - (this[offset + 3]) -} +ISOBox.prototype._procSubBoxes = function(name, length) { + var i; + if (this._parsing) { + this[name] = []; + for (i = 0; i < length; i++) { + this[name].push(ISOBox.parse(this)); + } + } + else { + for (i = 0; i < length; i++) { + if (this._rawo) { + this[name][i].write(); + } else { + this.size += this[name][i].getLength(); + } + } + } +}; -Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, true, 23, 4) -} +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Read/parse functions -Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 4, this.length) - return ieee754.read(this, offset, false, 23, 4) -} +ISOBox.prototype._readField = function(type, size) { + switch (type) { + case 'uint': + return this._readUint(size); + case 'int': + return this._readInt(size); + case 'template': + return this._readTemplate(size); + case 'string': + return (size === -1) ? this._readTerminatedString() : this._readString(size); + case 'data': + return this._readData(size); + case 'utf8': + return this._readUTF8String(); + default: + return -1; + } +}; -Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, true, 52, 8) -} +ISOBox.prototype._readInt = function(size) { + var result = null, + offset = this._cursor.offset - this._raw.byteOffset; + switch(size) { + case 8: + result = this._raw.getInt8(offset); + break; + case 16: + result = this._raw.getInt16(offset); + break; + case 32: + result = this._raw.getInt32(offset); + break; + case 64: + // Warning: JavaScript cannot handle 64-bit integers natively. + // This will give unexpected results for integers >= 2^53 + var s1 = this._raw.getInt32(offset); + var s2 = this._raw.getInt32(offset + 4); + result = (s1 * Math.pow(2,32)) + s2; + break; + } + this._cursor.offset += (size >> 3); + return result; +}; -Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { - if (!noAssert) checkOffset(offset, 8, this.length) - return ieee754.read(this, offset, false, 52, 8) -} +ISOBox.prototype._readUint = function(size) { + var result = null, + offset = this._cursor.offset - this._raw.byteOffset, + s1, s2; + switch(size) { + case 8: + result = this._raw.getUint8(offset); + break; + case 16: + result = this._raw.getUint16(offset); + break; + case 24: + s1 = this._raw.getUint16(offset); + s2 = this._raw.getUint8(offset + 2); + result = (s1 << 8) + s2; + break; + case 32: + result = this._raw.getUint32(offset); + break; + case 64: + // Warning: JavaScript cannot handle 64-bit integers natively. + // This will give unexpected results for integers >= 2^53 + s1 = this._raw.getUint32(offset); + s2 = this._raw.getUint32(offset + 4); + result = (s1 * Math.pow(2,32)) + s2; + break; + } + this._cursor.offset += (size >> 3); + return result; +}; -function checkInt (buf, value, offset, ext, max, min) { - if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') - if (value > max || value < min) throw new RangeError('value is out of bounds') - if (offset + ext > buf.length) throw new RangeError('index out of range') -} +ISOBox.prototype._readString = function(length) { + var str = ''; + for (var c = 0; c < length; c++) { + var char = this._readUint(8); + str += String.fromCharCode(char); + } + return str; +}; -Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) +ISOBox.prototype._readTemplate = function(size) { + var pre = this._readUint(size / 2); + var post = this._readUint(size / 2); + return pre + (post / Math.pow(2, size / 2)); +}; - var mul = 1 - var i = 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF +ISOBox.prototype._readTerminatedString = function() { + var str = ''; + while (this._cursor.offset - this._offset < this._raw.byteLength) { + var char = this._readUint(8); + if (char === 0) break; + str += String.fromCharCode(char); } + return str; +}; - return offset + byteLength -} - -Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - byteLength = byteLength | 0 - if (!noAssert) checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) +ISOBox.prototype._readData = function(size) { + var length = (size > 0) ? size : (this._raw.byteLength - (this._cursor.offset - this._offset)); + if (length > 0) { + var data = new Uint8Array(this._raw.buffer, this._cursor.offset, length); - var i = byteLength - 1 - var mul = 1 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = (value / mul) & 0xFF + this._cursor.offset += length; + return data; + } + else { + return null; } +}; - return offset + byteLength -} +ISOBox.prototype._readUTF8String = function() { + var length = this._raw.byteLength - (this._cursor.offset - this._offset); + var data = null; + if (length > 0) { + data = new DataView(this._raw.buffer, this._cursor.offset, length); + this._cursor.offset += length; + } + + return data ? ISOBoxer.Utils.dataViewToString(data) : data; +}; -Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - this[offset] = (value & 0xff) - return offset + 1 -} +ISOBox.prototype._parseBox = function() { + this._parsing = true; + this._cursor.offset = this._offset; -function objectWriteUInt16 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { - buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 + // return immediately if there are not enough bytes to read the header + if (this._offset + 8 > this._raw.buffer.byteLength) { + this._root._incomplete = true; + return; } -} -Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) - } - return offset + 2 -} + this._procField('size', 'uint', 32); + this._procField('type', 'string', 4); -Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} + if (this.size === 1) { this._procField('largesize', 'uint', 64); } + if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } -function objectWriteUInt32 (buf, value, offset, littleEndian) { - if (value < 0) value = 0xffffffff + value + 1 - for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { - buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + switch(this.size) { + case 0: + this._raw = new DataView(this._raw.buffer, this._offset, (this._raw.byteLength - this._cursor.offset + 8)); + break; + case 1: + if (this._offset + this.size > this._raw.buffer.byteLength) { + this._incomplete = true; + this._root._incomplete = true; + } else { + this._raw = new DataView(this._raw.buffer, this._offset, this.largesize); + } + break; + default: + if (this._offset + this.size > this._raw.buffer.byteLength) { + this._incomplete = true; + this._root._incomplete = true; + } else { + this._raw = new DataView(this._raw.buffer, this._offset, this.size); + } } -} -Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset + 3] = (value >>> 24) - this[offset + 2] = (value >>> 16) - this[offset + 1] = (value >>> 8) - this[offset] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, true) + // additional parsing + if (!this._incomplete) { + if (this._boxProcessors[this.type]) { + this._boxProcessors[this.type].call(this); + } + if (this._boxContainers.indexOf(this.type) !== -1) { + this._parseContainerBox(); + } else{ + // Unknown box => read and store box content + this._data = this._readData(); + } } - return offset + 4 -} +}; -Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) +ISOBox.prototype._parseFullBox = function() { + this.version = this._readUint(8); + this.flags = this._readUint(24); +}; + +ISOBox.prototype._parseContainerBox = function() { + this.boxes = []; + while (this._cursor.offset - this._raw.byteOffset < this._raw.byteLength) { + this.boxes.push(ISOBox.parse(this)); } - return offset + 4 -} +}; -Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Write functions - checkInt(this, value, offset, byteLength, limit - 1, -limit) - } +ISOBox.prototype.append = function(box, pos) { + ISOBoxer.Utils.appendBox(this, box, pos); +}; - var i = 0 - var mul = 1 - var sub = value < 0 ? 1 : 0 - this[offset] = value & 0xFF - while (++i < byteLength && (mul *= 0x100)) { - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF - } +ISOBox.prototype.getLength = function() { + this._parsing = false; + this._rawo = null; - return offset + byteLength -} + this.size = 0; + this._procField('size', 'uint', 32); + this._procField('type', 'string', 4); -Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) { - var limit = Math.pow(2, 8 * byteLength - 1) + if (this.size === 1) { this._procField('largesize', 'uint', 64); } + if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } - checkInt(this, value, offset, byteLength, limit - 1, -limit) + if (this._boxProcessors[this.type]) { + this._boxProcessors[this.type].call(this); } - var i = byteLength - 1 - var mul = 1 - var sub = value < 0 ? 1 : 0 - this[offset + i] = value & 0xFF - while (--i >= 0 && (mul *= 0x100)) { - this[offset + i] = ((value / mul) >> 0) - sub & 0xFF + if (this._boxContainers.indexOf(this.type) !== -1) { + for (var i = 0; i < this.boxes.length; i++) { + this.size += this.boxes[i].getLength(); + } + } + + if (this._data) { + this._writeData(this._data); } - return offset + byteLength -} + return this.size; +}; -Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) - if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) - if (value < 0) value = 0xff + value + 1 - this[offset] = (value & 0xff) - return offset + 1 -} +ISOBox.prototype.write = function() { + this._parsing = false; + this._cursor.offset = this._parent._cursor.offset; -Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - } else { - objectWriteUInt16(this, value, offset, true) + switch(this.size) { + case 0: + this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, (this.parent._rawo.byteLength - this._cursor.offset)); + break; + case 1: + this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.largesize); + break; + default: + this._rawo = new DataView(this._parent._rawo.buffer, this._cursor.offset, this.size); } - return offset + 2 -} -Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 8) - this[offset + 1] = (value & 0xff) - } else { - objectWriteUInt16(this, value, offset, false) - } - return offset + 2 -} + this._procField('size', 'uint', 32); + this._procField('type', 'string', 4); -Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value & 0xff) - this[offset + 1] = (value >>> 8) - this[offset + 2] = (value >>> 16) - this[offset + 3] = (value >>> 24) - } else { - objectWriteUInt32(this, value, offset, true) + if (this.size === 1) { this._procField('largesize', 'uint', 64); } + if (this.type === 'uuid') { this._procFieldArray('usertype', 16, 'uint', 8); } + + if (this._boxProcessors[this.type]) { + this._boxProcessors[this.type].call(this); } - return offset + 4 -} -Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { - value = +value - offset = offset | 0 - if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) - if (value < 0) value = 0xffffffff + value + 1 - if (Buffer.TYPED_ARRAY_SUPPORT) { - this[offset] = (value >>> 24) - this[offset + 1] = (value >>> 16) - this[offset + 2] = (value >>> 8) - this[offset + 3] = (value & 0xff) - } else { - objectWriteUInt32(this, value, offset, false) + if (this._boxContainers.indexOf(this.type) !== -1) { + for (var i = 0; i < this.boxes.length; i++) { + this.boxes[i].write(); + } + } + + if (this._data) { + this._writeData(this._data); } - return offset + 4 -} -function checkIEEE754 (buf, value, offset, ext, max, min) { - if (value > max || value < min) throw new RangeError('value is out of bounds') - if (offset + ext > buf.length) throw new RangeError('index out of range') - if (offset < 0) throw new RangeError('index out of range') -} + this._parent._cursor.offset += this.size; -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} + return this.size; +}; -Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} +ISOBox.prototype._writeInt = function(size, value) { + if (this._rawo) { + var offset = this._cursor.offset - this._rawo.byteOffset; + switch(size) { + case 8: + this._rawo.setInt8(offset, value); + break; + case 16: + this._rawo.setInt16(offset, value); + break; + case 32: + this._rawo.setInt32(offset, value); + break; + case 64: + // Warning: JavaScript cannot handle 64-bit integers natively. + // This will give unexpected results for integers >= 2^53 + var s1 = Math.floor(value / Math.pow(2,32)); + var s2 = value - (s1 * Math.pow(2,32)); + this._rawo.setUint32(offset, s1); + this._rawo.setUint32(offset + 4, s2); + break; + } + this._cursor.offset += (size >> 3); + } else { + this.size += (size >> 3); + } +}; -Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} +ISOBox.prototype._writeUint = function(size, value) { -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + if (this._rawo) { + var offset = this._cursor.offset - this._rawo.byteOffset, + s1, s2; + switch(size) { + case 8: + this._rawo.setUint8(offset, value); + break; + case 16: + this._rawo.setUint16(offset, value); + break; + case 24: + s1 = (value & 0xFFFF00) >> 8; + s2 = (value & 0x0000FF); + this._rawo.setUint16(offset, s1); + this._rawo.setUint8(offset + 2, s2); + break; + case 32: + this._rawo.setUint32(offset, value); + break; + case 64: + // Warning: JavaScript cannot handle 64-bit integers natively. + // This will give unexpected results for integers >= 2^53 + s1 = Math.floor(value / Math.pow(2,32)); + s2 = value - (s1 * Math.pow(2,32)); + this._rawo.setUint32(offset, s1); + this._rawo.setUint32(offset + 4, s2); + break; + } + this._cursor.offset += (size >> 3); + } else { + this.size += (size >> 3); } - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} +}; -Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} +ISOBox.prototype._writeString = function(size, str) { + for (var c = 0; c < size; c++) { + this._writeUint(8, str.charCodeAt(c)); + } +}; -Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} +ISOBox.prototype._writeTerminatedString = function(str) { + if (str.length === 0) { + return; + } + for (var c = 0; c < str.length; c++) { + this._writeUint(8, str.charCodeAt(c)); + } + this._writeUint(8, 0); +}; -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function copy (target, targetStart, start, end) { - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (targetStart >= target.length) targetStart = target.length - if (!targetStart) targetStart = 0 - if (end > 0 && end < start) end = start +ISOBox.prototype._writeTemplate = function(size, value) { + var pre = Math.floor(value); + var post = (value - pre) * Math.pow(2, size / 2); + this._writeUint(size / 2, pre); + this._writeUint(size / 2, post); +}; - // Copy 0 bytes; we're done - if (end === start) return 0 - if (target.length === 0 || this.length === 0) return 0 +ISOBox.prototype._writeData = function(data) { + var i; + //data to copy + if (data) { + if (this._rawo) { + //Array and Uint8Array has also to be managed + if (data instanceof Array) { + var offset = this._cursor.offset - this._rawo.byteOffset; + for (var i = 0; i < data.length; i++) { + this._rawo.setInt8(offset + i, data[i]); + } + this._cursor.offset += data.length; + } - // Fatal error conditions - if (targetStart < 0) { - throw new RangeError('targetStart out of bounds') - } - if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds') - if (end < 0) throw new RangeError('sourceEnd out of bounds') + if (data instanceof Uint8Array) { + this._root.bytes.set(data, this._cursor.offset); + this._cursor.offset += data.length; + } - // Are we oob? - if (end > this.length) end = this.length - if (target.length - targetStart < end - start) { - end = target.length - targetStart + start + } else { + //nothing to copy only size to compute + this.size += data.length; + } } +}; - var len = end - start - var i - - if (this === target && start < targetStart && targetStart < end) { - // descending copy from end - for (i = len - 1; i >= 0; i--) { - target[i + targetStart] = this[i + start] - } - } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { - // ascending copy from start - for (i = 0; i < len; i++) { - target[i + targetStart] = this[i + start] +ISOBox.prototype._writeUTF8String = function(string) { + var u = ISOBoxer.Utils.utf8ToByteArray(string); + if (this._rawo) { + var dataView = new DataView(this._rawo.buffer, this._cursor.offset, u.length); + for (var i = 0; i < u.length; i++) { + dataView.setUint8(i, u[i]); } } else { - target._set(this.subarray(start, start + len), targetStart) + this.size += u.length; } +}; - return len -} - -// fill(value, start=0, end=buffer.length) -Buffer.prototype.fill = function fill (value, start, end) { - if (!value) value = 0 - if (!start) start = 0 - if (!end) end = this.length +ISOBox.prototype._writeField = function(type, size, value) { + switch (type) { + case 'uint': + this._writeUint(size, value); + break; + case 'int': + this._writeInt(size, value); + break; + case 'template': + this._writeTemplate(size, value); + break; + case 'string': + if (size == -1) { + this._writeTerminatedString(value); + } else { + this._writeString(size, value); + } + break; + case 'data': + this._writeData(value); + break; + case 'utf8': + this._writeUTF8String(value); + break; + default: + break; + } +}; - if (end < start) throw new RangeError('end < start') +// ISO/IEC 14496-15:2014 - avc1 box +ISOBox.prototype._boxProcessors['avc1'] = ISOBox.prototype._boxProcessors['encv'] = function() { + // SampleEntry fields + this._procFieldArray('reserved1', 6, 'uint', 8); + this._procField('data_reference_index', 'uint', 16); + // VisualSampleEntry fields + this._procField('pre_defined1', 'uint', 16); + this._procField('reserved2', 'uint', 16); + this._procFieldArray('pre_defined2', 3, 'uint', 32); + this._procField('width', 'uint', 16); + this._procField('height', 'uint', 16); + this._procField('horizresolution', 'template', 32); + this._procField('vertresolution', 'template', 32); + this._procField('reserved3', 'uint', 32); + this._procField('frame_count', 'uint', 16); + this._procFieldArray('compressorname', 32,'uint', 8); + this._procField('depth', 'uint', 16); + this._procField('pre_defined3', 'int', 16); + // AVCSampleEntry fields + this._procField('config', 'data', -1); +}; - // Fill 0 bytes; we're done - if (end === start) return - if (this.length === 0) return +// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box +ISOBox.prototype._boxProcessors['dref'] = function() { + this._procFullBox(); + this._procField('entry_count', 'uint', 32); + this._procSubBoxes('entries', this.entry_count); +}; - if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') - if (end < 0 || end > this.length) throw new RangeError('end out of bounds') +// ISO/IEC 14496-12:2012 - 8.6.6 Edit List Box +ISOBox.prototype._boxProcessors['elst'] = function() { + this._procFullBox(); + this._procField('entry_count', 'uint', 32); + this._procEntries('entries', this.entry_count, function(entry) { + this._procEntryField(entry, 'segment_duration', 'uint', (this.version === 1) ? 64 : 32); + this._procEntryField(entry, 'media_time', 'int', (this.version === 1) ? 64 : 32); + this._procEntryField(entry, 'media_rate_integer', 'int', 16); + this._procEntryField(entry, 'media_rate_fraction', 'int', 16); + }); +}; - var i - if (typeof value === 'number') { - for (i = start; i < end; i++) { - this[i] = value - } +// ISO/IEC 23009-1:2014 - 5.10.3.3 Event Message Box +ISOBox.prototype._boxProcessors['emsg'] = function() { + this._procFullBox(); + if (this.version == 1) { + this._procField('timescale', 'uint', 32); + this._procField('presentation_time', 'uint', 64); + this._procField('event_duration', 'uint', 32); + this._procField('id', 'uint', 32); + this._procField('scheme_id_uri', 'string', -1); + this._procField('value', 'string', -1); } else { - var bytes = utf8ToBytes(value.toString()) - var len = bytes.length - for (i = start; i < end; i++) { - this[i] = bytes[i % len] - } + this._procField('scheme_id_uri', 'string', -1); + this._procField('value', 'string', -1); + this._procField('timescale', 'uint', 32); + this._procField('presentation_time_delta', 'uint', 32); + this._procField('event_duration', 'uint', 32); + this._procField('id', 'uint', 32); } + this._procField('message_data', 'data', -1); +}; +// ISO/IEC 14496-12:2012 - 8.1.2 Free Space Box +ISOBox.prototype._boxProcessors['free'] = ISOBox.prototype._boxProcessors['skip'] = function() { + this._procField('data', 'data', -1); +}; - return this -} - -/** - * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. - * Added in Node 0.12. Only available in browsers that support ArrayBuffer. - */ -Buffer.prototype.toArrayBuffer = function toArrayBuffer () { - if (typeof Uint8Array !== 'undefined') { - if (Buffer.TYPED_ARRAY_SUPPORT) { - return (new Buffer(this)).buffer - } else { - var buf = new Uint8Array(this.length) - for (var i = 0, len = buf.length; i < len; i += 1) { - buf[i] = this[i] - } - return buf.buffer - } - } else { - throw new TypeError('Buffer.toArrayBuffer not supported in this browser') +// ISO/IEC 14496-12:2012 - 8.12.2 Original Format Box +ISOBox.prototype._boxProcessors['frma'] = function() { + this._procField('data_format', 'uint', 32); +}; +// ISO/IEC 14496-12:2012 - 4.3 File Type Box / 8.16.2 Segment Type Box +ISOBox.prototype._boxProcessors['ftyp'] = +ISOBox.prototype._boxProcessors['styp'] = function() { + this._procField('major_brand', 'string', 4); + this._procField('minor_version', 'uint', 32); + var nbCompatibleBrands = -1; + if (this._parsing) { + nbCompatibleBrands = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset)) / 4; } -} - -// HELPER FUNCTIONS -// ================ - -var BP = Buffer.prototype - -/** - * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods - */ -Buffer._augment = function _augment (arr) { - arr.constructor = Buffer - arr._isBuffer = true - - // save reference to original Uint8Array set method before overwriting - arr._set = arr.set - - // deprecated - arr.get = BP.get - arr.set = BP.set - - arr.write = BP.write - arr.toString = BP.toString - arr.toLocaleString = BP.toString - arr.toJSON = BP.toJSON - arr.equals = BP.equals - arr.compare = BP.compare - arr.indexOf = BP.indexOf - arr.copy = BP.copy - arr.slice = BP.slice - arr.readUIntLE = BP.readUIntLE - arr.readUIntBE = BP.readUIntBE - arr.readUInt8 = BP.readUInt8 - arr.readUInt16LE = BP.readUInt16LE - arr.readUInt16BE = BP.readUInt16BE - arr.readUInt32LE = BP.readUInt32LE - arr.readUInt32BE = BP.readUInt32BE - arr.readIntLE = BP.readIntLE - arr.readIntBE = BP.readIntBE - arr.readInt8 = BP.readInt8 - arr.readInt16LE = BP.readInt16LE - arr.readInt16BE = BP.readInt16BE - arr.readInt32LE = BP.readInt32LE - arr.readInt32BE = BP.readInt32BE - arr.readFloatLE = BP.readFloatLE - arr.readFloatBE = BP.readFloatBE - arr.readDoubleLE = BP.readDoubleLE - arr.readDoubleBE = BP.readDoubleBE - arr.writeUInt8 = BP.writeUInt8 - arr.writeUIntLE = BP.writeUIntLE - arr.writeUIntBE = BP.writeUIntBE - arr.writeUInt16LE = BP.writeUInt16LE - arr.writeUInt16BE = BP.writeUInt16BE - arr.writeUInt32LE = BP.writeUInt32LE - arr.writeUInt32BE = BP.writeUInt32BE - arr.writeIntLE = BP.writeIntLE - arr.writeIntBE = BP.writeIntBE - arr.writeInt8 = BP.writeInt8 - arr.writeInt16LE = BP.writeInt16LE - arr.writeInt16BE = BP.writeInt16BE - arr.writeInt32LE = BP.writeInt32LE - arr.writeInt32BE = BP.writeInt32BE - arr.writeFloatLE = BP.writeFloatLE - arr.writeFloatBE = BP.writeFloatBE - arr.writeDoubleLE = BP.writeDoubleLE - arr.writeDoubleBE = BP.writeDoubleBE - arr.fill = BP.fill - arr.inspect = BP.inspect - arr.toArrayBuffer = BP.toArrayBuffer + this._procFieldArray('compatible_brands', nbCompatibleBrands, 'string', 4); +}; - return arr -} +// ISO/IEC 14496-12:2012 - 8.4.3 Handler Reference Box +ISOBox.prototype._boxProcessors['hdlr'] = function() { + this._procFullBox(); + this._procField('pre_defined', 'uint', 32); + this._procField('handler_type', 'string', 4); + this._procFieldArray('reserved', 3, 'uint', 32); + this._procField('name', 'string', -1); +}; -var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g +// ISO/IEC 14496-12:2012 - 8.1.1 Media Data Box +ISOBox.prototype._boxProcessors['mdat'] = function() { + this._procField('data', 'data', -1); +}; -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node converts strings with length < 2 to '' - if (str.length < 2) return '' - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' +// ISO/IEC 14496-12:2012 - 8.4.2 Media Header Box +ISOBox.prototype._boxProcessors['mdhd'] = function() { + this._procFullBox(); + this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); + this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); + this._procField('timescale', 'uint', 32); + this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); + if (!this._parsing && typeof this.language === 'string') { + // In case of writing and language has been set as a string, then convert it into char codes array + this.language = ((this.language.charCodeAt(0) - 0x60) << 10) | + ((this.language.charCodeAt(1) - 0x60) << 5) | + ((this.language.charCodeAt(2) - 0x60)); } - return str -} + this._procField('language', 'uint', 16); + if (this._parsing) { + this.language = String.fromCharCode(((this.language >> 10) & 0x1F) + 0x60, + ((this.language >> 5) & 0x1F) + 0x60, + (this.language & 0x1F) + 0x60); + } + this._procField('pre_defined', 'uint', 16); +}; -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} +// ISO/IEC 14496-12:2012 - 8.8.2 Movie Extends Header Box +ISOBox.prototype._boxProcessors['mehd'] = function() { + this._procFullBox(); + this._procField('fragment_duration', 'uint', (this.version == 1) ? 64 : 32); +}; -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} +// ISO/IEC 14496-12:2012 - 8.8.5 Movie Fragment Header Box +ISOBox.prototype._boxProcessors['mfhd'] = function() { + this._procFullBox(); + this._procField('sequence_number', 'uint', 32); +}; -function utf8ToBytes (string, units) { - units = units || Infinity - var codePoint - var length = string.length - var leadSurrogate = null - var bytes = [] +// ISO/IEC 14496-12:2012 - 8.8.11 Movie Fragment Random Access Box +ISOBox.prototype._boxProcessors['mfro'] = function() { + this._procFullBox(); + this._procField('mfra_size', 'uint', 32); // Called mfra_size to distinguish from the normal "size" attribute of a box +}; - for (var i = 0; i < length; i++) { - codePoint = string.charCodeAt(i) - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (!leadSurrogate) { - // no lead yet - if (codePoint > 0xDBFF) { - // unexpected trail - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } else if (i + 1 === length) { - // unpaired lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - continue - } +// ISO/IEC 14496-12:2012 - 8.5.2.2 mp4a box (use AudioSampleEntry definition and naming) +ISOBox.prototype._boxProcessors['mp4a'] = ISOBox.prototype._boxProcessors['enca'] = function() { + // SampleEntry fields + this._procFieldArray('reserved1', 6, 'uint', 8); + this._procField('data_reference_index', 'uint', 16); + // AudioSampleEntry fields + this._procFieldArray('reserved2', 2, 'uint', 32); + this._procField('channelcount', 'uint', 16); + this._procField('samplesize', 'uint', 16); + this._procField('pre_defined', 'uint', 16); + this._procField('reserved3', 'uint', 16); + this._procField('samplerate', 'template', 32); + // ESDescriptor fields + this._procField('esds', 'data', -1); +}; - // valid lead - leadSurrogate = codePoint +// ISO/IEC 14496-12:2012 - 8.2.2 Movie Header Box +ISOBox.prototype._boxProcessors['mvhd'] = function() { + this._procFullBox(); + this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); + this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); + this._procField('timescale', 'uint', 32); + this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); + this._procField('rate', 'template', 32); + this._procField('volume', 'template', 16); + this._procField('reserved1', 'uint', 16); + this._procFieldArray('reserved2', 2, 'uint', 32); + this._procFieldArray('matrix', 9, 'template', 32); + this._procFieldArray('pre_defined', 6,'uint', 32); + this._procField('next_track_ID', 'uint', 32); +}; - continue - } +// ISO/IEC 14496-30:2014 - WebVTT Cue Payload Box. +ISOBox.prototype._boxProcessors['payl'] = function() { + this._procField('cue_text', 'utf8'); +}; - // 2 leads in a row - if (codePoint < 0xDC00) { - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) - leadSurrogate = codePoint - continue - } +//ISO/IEC 23001-7:2011 - 8.1 Protection System Specific Header Box +ISOBox.prototype._boxProcessors['pssh'] = function() { + this._procFullBox(); + + this._procFieldArray('SystemID', 16, 'uint', 8); + this._procField('DataSize', 'uint', 32); + this._procFieldArray('Data', this.DataSize, 'uint', 8); +}; +// ISO/IEC 14496-12:2012 - 8.12.5 Scheme Type Box +ISOBox.prototype._boxProcessors['schm'] = function() { + this._procFullBox(); + + this._procField('scheme_type', 'uint', 32); + this._procField('scheme_version', 'uint', 32); - // valid surrogate pair - codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000 - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) + if (this.flags & 0x000001) { + this._procField('scheme_uri', 'string', -1); } +}; +// ISO/IEC 14496-12:2012 - 8.6.4.1 sdtp box +ISOBox.prototype._boxProcessors['sdtp'] = function() { + this._procFullBox(); - leadSurrogate = null - - // encode utf8 - if (codePoint < 0x80) { - if ((units -= 1) < 0) break - bytes.push(codePoint) - } else if (codePoint < 0x800) { - if ((units -= 2) < 0) break - bytes.push( - codePoint >> 0x6 | 0xC0, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x10000) { - if ((units -= 3) < 0) break - bytes.push( - codePoint >> 0xC | 0xE0, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else if (codePoint < 0x110000) { - if ((units -= 4) < 0) break - bytes.push( - codePoint >> 0x12 | 0xF0, - codePoint >> 0xC & 0x3F | 0x80, - codePoint >> 0x6 & 0x3F | 0x80, - codePoint & 0x3F | 0x80 - ) - } else { - throw new Error('Invalid code point') - } + var sample_count = -1; + if (this._parsing) { + sample_count = (this._raw.byteLength - (this._cursor.offset - this._raw.byteOffset)); } - return bytes -} + this._procFieldArray('sample_dependency_table', sample_count, 'uint', 8); +}; -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; i++) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} +// ISO/IEC 14496-12:2012 - 8.16.3 Segment Index Box +ISOBox.prototype._boxProcessors['sidx'] = function() { + this._procFullBox(); + this._procField('reference_ID', 'uint', 32); + this._procField('timescale', 'uint', 32); + this._procField('earliest_presentation_time', 'uint', (this.version == 1) ? 64 : 32); + this._procField('first_offset', 'uint', (this.version == 1) ? 64 : 32); + this._procField('reserved', 'uint', 16); + this._procField('reference_count', 'uint', 16); + this._procEntries('references', this.reference_count, function(entry) { + if (!this._parsing) { + entry.reference = (entry.reference_type & 0x00000001) << 31; + entry.reference |= (entry.referenced_size & 0x7FFFFFFF); + entry.sap = (entry.starts_with_SAP & 0x00000001) << 31; + entry.sap |= (entry.SAP_type & 0x00000003) << 28; + entry.sap |= (entry.SAP_delta_time & 0x0FFFFFFF); + } + this._procEntryField(entry, 'reference', 'uint', 32); + this._procEntryField(entry, 'subsegment_duration', 'uint', 32); + this._procEntryField(entry, 'sap', 'uint', 32); + if (this._parsing) { + entry.reference_type = (entry.reference >> 31) & 0x00000001; + entry.referenced_size = entry.reference & 0x7FFFFFFF; + entry.starts_with_SAP = (entry.sap >> 31) & 0x00000001; + entry.SAP_type = (entry.sap >> 28) & 0x00000007; + entry.SAP_delta_time = (entry.sap & 0x0FFFFFFF); + } + }); +}; -function utf16leToBytes (str, units) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; i++) { - if ((units -= 2) < 0) break +// ISO/IEC 14496-12:2012 - 8.4.5.3 Sound Media Header Box +ISOBox.prototype._boxProcessors['smhd'] = function() { + this._procFullBox(); + this._procField('balance', 'uint', 16); + this._procField('reserved', 'uint', 16); +}; - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} +// ISO/IEC 14496-12:2012 - 8.16.4 Subsegment Index Box +ISOBox.prototype._boxProcessors['ssix'] = function() { + this._procFullBox(); + this._procField('subsegment_count', 'uint', 32); + this._procEntries('subsegments', this.subsegment_count, function(subsegment) { + this._procEntryField(subsegment, 'ranges_count', 'uint', 32); + this._procSubEntries(subsegment, 'ranges', subsegment.ranges_count, function(range) { + this._procEntryField(range, 'level', 'uint', 8); + this._procEntryField(range, 'range_size', 'uint', 24); + }); + }); +}; -function base64ToBytes (str) { - return base64.toByteArray(base64clean(str)) -} +// ISO/IEC 14496-12:2012 - 8.5.2 Sample Description Box +ISOBox.prototype._boxProcessors['stsd'] = function() { + this._procFullBox(); + this._procField('entry_count', 'uint', 32); + this._procSubBoxes('entries', this.entry_count); +}; -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; i++) { - if ((i + offset >= dst.length) || (i >= src.length)) break - dst[i + offset] = src[i] - } - return i -} +// ISO/IEC 14496-12:2015 - 8.7.7 Sub-Sample Information Box +ISOBox.prototype._boxProcessors['subs'] = function () { + this._procFullBox(); + this._procField('entry_count', 'uint', 32); + this._procEntries('entries', this.entry_count, function(entry) { + this._procEntryField(entry, 'sample_delta', 'uint', 32); + this._procEntryField(entry, 'subsample_count', 'uint', 16); + this._procSubEntries(entry, 'subsamples', entry.subsample_count, function(subsample) { + this._procEntryField(subsample, 'subsample_size', 'uint', (this.version === 1) ? 32 : 16); + this._procEntryField(subsample, 'subsample_priority', 'uint', 8); + this._procEntryField(subsample, 'discardable', 'uint', 8); + this._procEntryField(subsample, 'codec_specific_parameters', 'uint', 32); + }); + }); +}; -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +//ISO/IEC 23001-7:2011 - 8.2 Track Encryption Box +ISOBox.prototype._boxProcessors['tenc'] = function() { + this._procFullBox(); -},{"11":11,"14":14,"8":8}],11:[function(_dereq_,module,exports){ -var toString = {}.toString; + this._procField('default_IsEncrypted', 'uint', 24); + this._procField('default_IV_size', 'uint', 8); + this._procFieldArray('default_KID', 16, 'uint', 8); + }; -module.exports = Array.isArray || function (arr) { - return toString.call(arr) == '[object Array]'; +// ISO/IEC 14496-12:2012 - 8.8.12 Track Fragmnent Decode Time +ISOBox.prototype._boxProcessors['tfdt'] = function() { + this._procFullBox(); + this._procField('baseMediaDecodeTime', 'uint', (this.version == 1) ? 64 : 32); }; -},{}],12:[function(_dereq_,module,exports){ -(function (Buffer){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. +// ISO/IEC 14496-12:2012 - 8.8.7 Track Fragment Header Box +ISOBox.prototype._boxProcessors['tfhd'] = function() { + this._procFullBox(); + this._procField('track_ID', 'uint', 32); + if (this.flags & 0x01) this._procField('base_data_offset', 'uint', 64); + if (this.flags & 0x02) this._procField('sample_description_offset', 'uint', 32); + if (this.flags & 0x08) this._procField('default_sample_duration', 'uint', 32); + if (this.flags & 0x10) this._procField('default_sample_size', 'uint', 32); + if (this.flags & 0x20) this._procField('default_sample_flags', 'uint', 32); +}; -function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); +// ISO/IEC 14496-12:2012 - 8.8.10 Track Fragment Random Access Box +ISOBox.prototype._boxProcessors['tfra'] = function() { + this._procFullBox(); + this._procField('track_ID', 'uint', 32); + if (!this._parsing) { + this.reserved = 0; + this.reserved |= (this.length_size_of_traf_num & 0x00000030) << 4; + this.reserved |= (this.length_size_of_trun_num & 0x0000000C) << 2; + this.reserved |= (this.length_size_of_sample_num & 0x00000003); } - return objectToString(arg) === '[object Array]'; -} -exports.isArray = isArray; - -function isBoolean(arg) { - return typeof arg === 'boolean'; -} -exports.isBoolean = isBoolean; - -function isNull(arg) { - return arg === null; -} -exports.isNull = isNull; - -function isNullOrUndefined(arg) { - return arg == null; -} -exports.isNullOrUndefined = isNullOrUndefined; - -function isNumber(arg) { - return typeof arg === 'number'; -} -exports.isNumber = isNumber; - -function isString(arg) { - return typeof arg === 'string'; -} -exports.isString = isString; - -function isSymbol(arg) { - return typeof arg === 'symbol'; -} -exports.isSymbol = isSymbol; - -function isUndefined(arg) { - return arg === void 0; -} -exports.isUndefined = isUndefined; - -function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; -} -exports.isRegExp = isRegExp; + this._procField('reserved', 'uint', 32); + if (this._parsing) { + this.length_size_of_traf_num = (this.reserved & 0x00000030) >> 4; + this.length_size_of_trun_num = (this.reserved & 0x0000000C) >> 2; + this.length_size_of_sample_num = (this.reserved & 0x00000003); + } + this._procField('number_of_entry', 'uint', 32); + this._procEntries('entries', this.number_of_entry, function(entry) { + this._procEntryField(entry, 'time', 'uint', (this.version === 1) ? 64 : 32); + this._procEntryField(entry, 'moof_offset', 'uint', (this.version === 1) ? 64 : 32); + this._procEntryField(entry, 'traf_number', 'uint', (this.length_size_of_traf_num + 1) * 8); + this._procEntryField(entry, 'trun_number', 'uint', (this.length_size_of_trun_num + 1) * 8); + this._procEntryField(entry, 'sample_number', 'uint', (this.length_size_of_sample_num + 1) * 8); + }); +}; -function isObject(arg) { - return typeof arg === 'object' && arg !== null; -} -exports.isObject = isObject; +// ISO/IEC 14496-12:2012 - 8.3.2 Track Header Box +ISOBox.prototype._boxProcessors['tkhd'] = function() { + this._procFullBox(); + this._procField('creation_time', 'uint', (this.version == 1) ? 64 : 32); + this._procField('modification_time', 'uint', (this.version == 1) ? 64 : 32); + this._procField('track_ID', 'uint', 32); + this._procField('reserved1', 'uint', 32); + this._procField('duration', 'uint', (this.version == 1) ? 64 : 32); + this._procFieldArray('reserved2', 2, 'uint', 32); + this._procField('layer', 'uint', 16); + this._procField('alternate_group', 'uint', 16); + this._procField('volume', 'template', 16); + this._procField('reserved3', 'uint', 16); + this._procFieldArray('matrix', 9, 'template', 32); + this._procField('width', 'template', 32); + this._procField('height', 'template', 32); +}; -function isDate(d) { - return objectToString(d) === '[object Date]'; -} -exports.isDate = isDate; +// ISO/IEC 14496-12:2012 - 8.8.3 Track Extends Box +ISOBox.prototype._boxProcessors['trex'] = function() { + this._procFullBox(); + this._procField('track_ID', 'uint', 32); + this._procField('default_sample_description_index', 'uint', 32); + this._procField('default_sample_duration', 'uint', 32); + this._procField('default_sample_size', 'uint', 32); + this._procField('default_sample_flags', 'uint', 32); +}; -function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); -} -exports.isError = isError; +// ISO/IEC 14496-12:2012 - 8.8.8 Track Run Box +// Note: the 'trun' box has a direct relation to the 'tfhd' box for defaults. +// These defaults are not set explicitly here, but are left to resolve for the user. +ISOBox.prototype._boxProcessors['trun'] = function() { + this._procFullBox(); + this._procField('sample_count', 'uint', 32); + if (this.flags & 0x1) this._procField('data_offset', 'int', 32); + if (this.flags & 0x4) this._procField('first_sample_flags', 'uint', 32); + this._procEntries('samples', this.sample_count, function(sample) { + if (this.flags & 0x100) this._procEntryField(sample, 'sample_duration', 'uint', 32); + if (this.flags & 0x200) this._procEntryField(sample, 'sample_size', 'uint', 32); + if (this.flags & 0x400) this._procEntryField(sample, 'sample_flags', 'uint', 32); + if (this.flags & 0x800) this._procEntryField(sample, 'sample_composition_time_offset', (this.version === 1) ? 'int' : 'uint', 32); + }); +}; -function isFunction(arg) { - return typeof arg === 'function'; -} -exports.isFunction = isFunction; +// ISO/IEC 14496-12:2012 - 8.7.2 Data Reference Box +ISOBox.prototype._boxProcessors['url '] = ISOBox.prototype._boxProcessors['urn '] = function() { + this._procFullBox(); + if (this.type === 'urn ') { + this._procField('name', 'string', -1); + } + this._procField('location', 'string', -1); +}; -function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; -} -exports.isPrimitive = isPrimitive; +// ISO/IEC 14496-30:2014 - WebVTT Source Label Box +ISOBox.prototype._boxProcessors['vlab'] = function() { + this._procField('source_label', 'utf8'); +}; -exports.isBuffer = Buffer.isBuffer; +// ISO/IEC 14496-12:2012 - 8.4.5.2 Video Media Header Box +ISOBox.prototype._boxProcessors['vmhd'] = function() { + this._procFullBox(); + this._procField('graphicsmode', 'uint', 16); + this._procFieldArray('opcolor', 3, 'uint', 16); +}; -function objectToString(o) { - return Object.prototype.toString.call(o); -} +// ISO/IEC 14496-30:2014 - WebVTT Configuration Box +ISOBox.prototype._boxProcessors['vttC'] = function() { + this._procField('config', 'utf8'); +}; -}).call(this,{"isBuffer":_dereq_(16)}) +// ISO/IEC 14496-30:2014 - WebVTT Empty Sample Box +ISOBox.prototype._boxProcessors['vtte'] = function() { + // Nothing should happen here. +}; -},{"16":16}],13:[function(_dereq_,module,exports){ +},{}],10:[function(_dereq_,module,exports){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a @@ -5142,8 +5227,16 @@ function objectToString(o) { // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. +var objectCreate = Object.create || objectCreatePolyfill +var objectKeys = Object.keys || objectKeysPolyfill +var bind = Function.prototype.bind || functionBindPolyfill + function EventEmitter() { - this._events = this._events || {}; + if (!this._events || !Object.prototype.hasOwnProperty.call(this, '_events')) { + this._events = objectCreate(null); + this._eventsCount = 0; + } + this._maxListeners = this._maxListeners || undefined; } module.exports = EventEmitter; @@ -5156,274 +5249,545 @@ EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; +var defaultMaxListeners = 10; + +var hasDefineProperty; +try { + var o = {}; + if (Object.defineProperty) Object.defineProperty(o, 'x', { value: 0 }); + hasDefineProperty = o.x === 0; +} catch (err) { hasDefineProperty = false } +if (hasDefineProperty) { + Object.defineProperty(EventEmitter, 'defaultMaxListeners', { + enumerable: true, + get: function() { + return defaultMaxListeners; + }, + set: function(arg) { + // check whether the input is a positive number (whose value is zero or + // greater and not a NaN). + if (typeof arg !== 'number' || arg < 0 || arg !== arg) + throw new TypeError('"defaultMaxListeners" must be a positive number'); + defaultMaxListeners = arg; + } + }); +} else { + EventEmitter.defaultMaxListeners = defaultMaxListeners; +} // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function(n) { - if (!isNumber(n) || n < 0 || isNaN(n)) - throw TypeError('n must be a positive number'); +EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { + if (typeof n !== 'number' || n < 0 || isNaN(n)) + throw new TypeError('"n" argument must be a positive number'); this._maxListeners = n; return this; }; -EventEmitter.prototype.emit = function(type) { - var er, handler, len, args, i, listeners; +function $getMaxListeners(that) { + if (that._maxListeners === undefined) + return EventEmitter.defaultMaxListeners; + return that._maxListeners; +} + +EventEmitter.prototype.getMaxListeners = function getMaxListeners() { + return $getMaxListeners(this); +}; + +// These standalone emit* functions are used to optimize calling of event +// handlers for fast cases because emit() itself often has a variable number of +// arguments and can be deoptimized because of that. These functions always have +// the same number of arguments and thus do not get deoptimized, so the code +// inside them can execute faster. +function emitNone(handler, isFn, self) { + if (isFn) + handler.call(self); + else { + var len = handler.length; + var listeners = arrayClone(handler, len); + for (var i = 0; i < len; ++i) + listeners[i].call(self); + } +} +function emitOne(handler, isFn, self, arg1) { + if (isFn) + handler.call(self, arg1); + else { + var len = handler.length; + var listeners = arrayClone(handler, len); + for (var i = 0; i < len; ++i) + listeners[i].call(self, arg1); + } +} +function emitTwo(handler, isFn, self, arg1, arg2) { + if (isFn) + handler.call(self, arg1, arg2); + else { + var len = handler.length; + var listeners = arrayClone(handler, len); + for (var i = 0; i < len; ++i) + listeners[i].call(self, arg1, arg2); + } +} +function emitThree(handler, isFn, self, arg1, arg2, arg3) { + if (isFn) + handler.call(self, arg1, arg2, arg3); + else { + var len = handler.length; + var listeners = arrayClone(handler, len); + for (var i = 0; i < len; ++i) + listeners[i].call(self, arg1, arg2, arg3); + } +} + +function emitMany(handler, isFn, self, args) { + if (isFn) + handler.apply(self, args); + else { + var len = handler.length; + var listeners = arrayClone(handler, len); + for (var i = 0; i < len; ++i) + listeners[i].apply(self, args); + } +} + +EventEmitter.prototype.emit = function emit(type) { + var er, handler, len, args, i, events; + var doError = (type === 'error'); - if (!this._events) - this._events = {}; + events = this._events; + if (events) + doError = (doError && events.error == null); + else if (!doError) + return false; // If there is no 'error' event listener then throw. - if (type === 'error') { - if (!this._events.error || - (isObject(this._events.error) && !this._events.error.length)) { + if (doError) { + if (arguments.length > 1) er = arguments[1]; - if (er instanceof Error) { - throw er; // Unhandled 'error' event - } - throw TypeError('Uncaught, unspecified "error" event.'); + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + // At least give some kind of context to the user + var err = new Error('Unhandled "error" event. (' + er + ')'); + err.context = er; + throw err; } + return false; } - handler = this._events[type]; + handler = events[type]; - if (isUndefined(handler)) + if (!handler) return false; - if (isFunction(handler)) { - switch (arguments.length) { + var isFn = typeof handler === 'function'; + len = arguments.length; + switch (len) { // fast cases - case 1: - handler.call(this); - break; - case 2: - handler.call(this, arguments[1]); - break; - case 3: - handler.call(this, arguments[1], arguments[2]); - break; + case 1: + emitNone(handler, isFn, this); + break; + case 2: + emitOne(handler, isFn, this, arguments[1]); + break; + case 3: + emitTwo(handler, isFn, this, arguments[1], arguments[2]); + break; + case 4: + emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); + break; // slower - default: - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - handler.apply(this, args); - } - } else if (isObject(handler)) { - len = arguments.length; - args = new Array(len - 1); - for (i = 1; i < len; i++) - args[i - 1] = arguments[i]; - - listeners = handler.slice(); - len = listeners.length; - for (i = 0; i < len; i++) - listeners[i].apply(this, args); + default: + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + emitMany(handler, isFn, this, args); } return true; }; -EventEmitter.prototype.addListener = function(type, listener) { +function _addListener(target, type, listener, prepend) { var m; + var events; + var existing; - if (!isFunction(listener)) - throw TypeError('listener must be a function'); + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); - if (!this._events) - this._events = {}; + events = target._events; + if (!events) { + events = target._events = objectCreate(null); + target._eventsCount = 0; + } else { + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (events.newListener) { + target.emit('newListener', type, + listener.listener ? listener.listener : listener); - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (this._events.newListener) - this.emit('newListener', type, - isFunction(listener.listener) ? - listener.listener : listener); + // Re-assign `events` because a newListener handler could have caused the + // this._events to be assigned to a new object + events = target._events; + } + existing = events[type]; + } - if (!this._events[type]) + if (!existing) { // Optimize the case of one listener. Don't need the extra array object. - this._events[type] = listener; - else if (isObject(this._events[type])) - // If we've already got an array, just append. - this._events[type].push(listener); - else - // Adding the second element, need to change to array. - this._events[type] = [this._events[type], listener]; - - // Check for listener leak - if (isObject(this._events[type]) && !this._events[type].warned) { - var m; - if (!isUndefined(this._maxListeners)) { - m = this._maxListeners; + existing = events[type] = listener; + ++target._eventsCount; + } else { + if (typeof existing === 'function') { + // Adding the second element, need to change to array. + existing = events[type] = + prepend ? [listener, existing] : [existing, listener]; } else { - m = EventEmitter.defaultMaxListeners; - } - - if (m && m > 0 && this._events[type].length > m) { - this._events[type].warned = true; - console.error('(node) warning: possible EventEmitter memory ' + - 'leak detected. %d listeners added. ' + - 'Use emitter.setMaxListeners() to increase limit.', - this._events[type].length); - if (typeof console.trace === 'function') { - // not supported in IE 10 - console.trace(); + // If we've already got an array, just append. + if (prepend) { + existing.unshift(listener); + } else { + existing.push(listener); + } + } + + // Check for listener leak + if (!existing.warned) { + m = $getMaxListeners(target); + if (m && m > 0 && existing.length > m) { + existing.warned = true; + var w = new Error('Possible EventEmitter memory leak detected. ' + + existing.length + ' "' + String(type) + '" listeners ' + + 'added. Use emitter.setMaxListeners() to ' + + 'increase limit.'); + w.name = 'MaxListenersExceededWarning'; + w.emitter = target; + w.type = type; + w.count = existing.length; + if (typeof console === 'object' && console.warn) { + console.warn('%s: %s', w.name, w.message); + } } } } - return this; + return target; +} + +EventEmitter.prototype.addListener = function addListener(type, listener) { + return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; -EventEmitter.prototype.once = function(type, listener) { - if (!isFunction(listener)) - throw TypeError('listener must be a function'); - - var fired = false; - - function g() { - this.removeListener(type, g); +EventEmitter.prototype.prependListener = + function prependListener(type, listener) { + return _addListener(this, type, listener, true); + }; - if (!fired) { - fired = true; - listener.apply(this, arguments); +function onceWrapper() { + if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); + this.fired = true; + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + var args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); } } +} - g.listener = listener; - this.on(type, g); +function _onceWrap(target, type, listener) { + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; + var wrapped = bind.call(onceWrapper, state); + wrapped.listener = listener; + state.wrapFn = wrapped; + return wrapped; +} +EventEmitter.prototype.once = function once(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.on(type, _onceWrap(this, type, listener)); return this; }; -// emits a 'removeListener' event iff the listener was removed -EventEmitter.prototype.removeListener = function(type, listener) { - var list, position, length, i; +EventEmitter.prototype.prependOnceListener = + function prependOnceListener(type, listener) { + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + this.prependListener(type, _onceWrap(this, type, listener)); + return this; + }; - if (!isFunction(listener)) - throw TypeError('listener must be a function'); +// Emits a 'removeListener' event if and only if the listener was removed. +EventEmitter.prototype.removeListener = + function removeListener(type, listener) { + var list, events, position, i, originalListener; + + if (typeof listener !== 'function') + throw new TypeError('"listener" argument must be a function'); + + events = this._events; + if (!events) + return this; + + list = events[type]; + if (!list) + return this; + + if (list === listener || list.listener === listener) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else { + delete events[type]; + if (events.removeListener) + this.emit('removeListener', type, list.listener || listener); + } + } else if (typeof list !== 'function') { + position = -1; + + for (i = list.length - 1; i >= 0; i--) { + if (list[i] === listener || list[i].listener === listener) { + originalListener = list[i].listener; + position = i; + break; + } + } - if (!this._events || !this._events[type]) - return this; + if (position < 0) + return this; - list = this._events[type]; - length = list.length; - position = -1; - - if (list === listener || - (isFunction(list.listener) && list.listener === listener)) { - delete this._events[type]; - if (this._events.removeListener) - this.emit('removeListener', type, listener); - - } else if (isObject(list)) { - for (i = length; i-- > 0;) { - if (list[i] === listener || - (list[i].listener && list[i].listener === listener)) { - position = i; - break; + if (position === 0) + list.shift(); + else + spliceOne(list, position); + + if (list.length === 1) + events[type] = list[0]; + + if (events.removeListener) + this.emit('removeListener', type, originalListener || listener); } - } - if (position < 0) return this; + }; - if (list.length === 1) { - list.length = 0; - delete this._events[type]; - } else { - list.splice(position, 1); - } +EventEmitter.prototype.removeAllListeners = + function removeAllListeners(type) { + var listeners, events, i; + + events = this._events; + if (!events) + return this; + + // not listening for removeListener, no need to emit + if (!events.removeListener) { + if (arguments.length === 0) { + this._events = objectCreate(null); + this._eventsCount = 0; + } else if (events[type]) { + if (--this._eventsCount === 0) + this._events = objectCreate(null); + else + delete events[type]; + } + return this; + } - if (this._events.removeListener) - this.emit('removeListener', type, listener); - } + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + var keys = objectKeys(events); + var key; + for (i = 0; i < keys.length; ++i) { + key = keys[i]; + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = objectCreate(null); + this._eventsCount = 0; + return this; + } - return this; -}; + listeners = events[type]; -EventEmitter.prototype.removeAllListeners = function(type) { - var key, listeners; + if (typeof listeners === 'function') { + this.removeListener(type, listeners); + } else if (listeners) { + // LIFO order + for (i = listeners.length - 1; i >= 0; i--) { + this.removeListener(type, listeners[i]); + } + } - if (!this._events) - return this; + return this; + }; - // not listening for removeListener, no need to emit - if (!this._events.removeListener) { - if (arguments.length === 0) - this._events = {}; - else if (this._events[type]) - delete this._events[type]; - return this; - } +function _listeners(target, type, unwrap) { + var events = target._events; - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - for (key in this._events) { - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = {}; - return this; - } + if (!events) + return []; - listeners = this._events[type]; + var evlistener = events[type]; + if (!evlistener) + return []; - if (isFunction(listeners)) { - this.removeListener(type, listeners); - } else { - // LIFO order - while (listeners.length) - this.removeListener(type, listeners[listeners.length - 1]); - } - delete this._events[type]; + if (typeof evlistener === 'function') + return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - return this; + return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); +} + +EventEmitter.prototype.listeners = function listeners(type) { + return _listeners(this, type, true); }; -EventEmitter.prototype.listeners = function(type) { - var ret; - if (!this._events || !this._events[type]) - ret = []; - else if (isFunction(this._events[type])) - ret = [this._events[type]]; - else - ret = this._events[type].slice(); - return ret; +EventEmitter.prototype.rawListeners = function rawListeners(type) { + return _listeners(this, type, false); }; EventEmitter.listenerCount = function(emitter, type) { - var ret; - if (!emitter._events || !emitter._events[type]) - ret = 0; - else if (isFunction(emitter._events[type])) - ret = 1; - else - ret = emitter._events[type].length; - return ret; + if (typeof emitter.listenerCount === 'function') { + return emitter.listenerCount(type); + } else { + return listenerCount.call(emitter, type); + } }; -function isFunction(arg) { - return typeof arg === 'function'; +EventEmitter.prototype.listenerCount = listenerCount; +function listenerCount(type) { + var events = this._events; + + if (events) { + var evlistener = events[type]; + + if (typeof evlistener === 'function') { + return 1; + } else if (evlistener) { + return evlistener.length; + } + } + + return 0; } -function isNumber(arg) { - return typeof arg === 'number'; +EventEmitter.prototype.eventNames = function eventNames() { + return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; +}; + +// About 1.5x faster than the two-arg version of Array#splice(). +function spliceOne(list, index) { + for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) + list[i] = list[k]; + list.pop(); } -function isObject(arg) { - return typeof arg === 'object' && arg !== null; +function arrayClone(arr, n) { + var copy = new Array(n); + for (var i = 0; i < n; ++i) + copy[i] = arr[i]; + return copy; } -function isUndefined(arg) { - return arg === void 0; +function unwrapListeners(arr) { + var ret = new Array(arr.length); + for (var i = 0; i < ret.length; ++i) { + ret[i] = arr[i].listener || arr[i]; + } + return ret; +} + +function objectCreatePolyfill(proto) { + var F = function() {}; + F.prototype = proto; + return new F; +} +function objectKeysPolyfill(obj) { + var keys = []; + for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k)) { + keys.push(k); + } + return k; +} +function functionBindPolyfill(context) { + var fn = this; + return function () { + return fn.apply(context, arguments); + }; } -},{}],14:[function(_dereq_,module,exports){ +},{}],11:[function(_dereq_,module,exports){ +'use strict'; + +var isArray = Array.isArray; +var keyList = Object.keys; +var hasProp = Object.prototype.hasOwnProperty; + +module.exports = function equal(a, b) { + if (a === b) return true; + + if (a && b && typeof a == 'object' && typeof b == 'object') { + var arrA = isArray(a) + , arrB = isArray(b) + , i + , length + , key; + + if (arrA && arrB) { + length = a.length; + if (length != b.length) return false; + for (i = length; i-- !== 0;) + if (!equal(a[i], b[i])) return false; + return true; + } + + if (arrA != arrB) return false; + + var dateA = a instanceof Date + , dateB = b instanceof Date; + if (dateA != dateB) return false; + if (dateA && dateB) return a.getTime() == b.getTime(); + + var regexpA = a instanceof RegExp + , regexpB = b instanceof RegExp; + if (regexpA != regexpB) return false; + if (regexpA && regexpB) return a.toString() == b.toString(); + + var keys = keyList(a); + length = keys.length; + + if (length !== keyList(b).length) + return false; + + for (i = length; i-- !== 0;) + if (!hasProp.call(b, keys[i])) return false; + + for (i = length; i-- !== 0;) { + key = keys[i]; + if (!equal(a[key], b[key])) return false; + } + + return true; + } + + return a!==a && b!==b; +}; + +},{}],12:[function(_dereq_,module,exports){ exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m var eLen = (nBytes * 8) - mLen - 1 @@ -5509,3365 +5873,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) { buffer[offset + i - d] |= s * 128 } -},{}],15:[function(_dereq_,module,exports){ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } -} - -},{}],16:[function(_dereq_,module,exports){ -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -module.exports = function (obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) -} - -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} - -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) -} - -},{}],17:[function(_dereq_,module,exports){ -(function (process){ -'use strict'; - -if (!process.version || - process.version.indexOf('v0.') === 0 || - process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { - module.exports = { nextTick: nextTick }; -} else { - module.exports = process -} - -function nextTick(fn, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); - } -} - - -}).call(this,_dereq_(18)) - -},{"18":18}],18:[function(_dereq_,module,exports){ -// shim for using process in browser -var process = module.exports = {}; - -// cached from whatever global is present so that test runners that stub it -// don't break things. But we need to wrap it in a try catch in case it is -// wrapped in strict mode code which doesn't define any globals. It's inside a -// function because try/catches deoptimize in certain engines. - -var cachedSetTimeout; -var cachedClearTimeout; - -function defaultSetTimout() { - throw new Error('setTimeout has not been defined'); -} -function defaultClearTimeout () { - throw new Error('clearTimeout has not been defined'); -} -(function () { - try { - if (typeof setTimeout === 'function') { - cachedSetTimeout = setTimeout; - } else { - cachedSetTimeout = defaultSetTimout; - } - } catch (e) { - cachedSetTimeout = defaultSetTimout; - } - try { - if (typeof clearTimeout === 'function') { - cachedClearTimeout = clearTimeout; - } else { - cachedClearTimeout = defaultClearTimeout; - } - } catch (e) { - cachedClearTimeout = defaultClearTimeout; - } -} ()) -function runTimeout(fun) { - if (cachedSetTimeout === setTimeout) { - //normal enviroments in sane situations - return setTimeout(fun, 0); - } - // if setTimeout wasn't available but was latter defined - if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { - cachedSetTimeout = setTimeout; - return setTimeout(fun, 0); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedSetTimeout(fun, 0); - } catch(e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedSetTimeout.call(null, fun, 0); - } catch(e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error - return cachedSetTimeout.call(this, fun, 0); - } - } - - -} -function runClearTimeout(marker) { - if (cachedClearTimeout === clearTimeout) { - //normal enviroments in sane situations - return clearTimeout(marker); - } - // if clearTimeout wasn't available but was latter defined - if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { - cachedClearTimeout = clearTimeout; - return clearTimeout(marker); - } - try { - // when when somebody has screwed with setTimeout but no I.E. maddness - return cachedClearTimeout(marker); - } catch (e){ - try { - // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally - return cachedClearTimeout.call(null, marker); - } catch (e){ - // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. - // Some versions of I.E. have different rules for clearTimeout vs setTimeout - return cachedClearTimeout.call(this, marker); - } - } - - - -} -var queue = []; -var draining = false; -var currentQueue; -var queueIndex = -1; - -function cleanUpNextTick() { - if (!draining || !currentQueue) { - return; - } - draining = false; - if (currentQueue.length) { - queue = currentQueue.concat(queue); - } else { - queueIndex = -1; - } - if (queue.length) { - drainQueue(); - } -} - -function drainQueue() { - if (draining) { - return; - } - var timeout = runTimeout(cleanUpNextTick); - draining = true; - - var len = queue.length; - while(len) { - currentQueue = queue; - queue = []; - while (++queueIndex < len) { - if (currentQueue) { - currentQueue[queueIndex].run(); - } - } - queueIndex = -1; - len = queue.length; - } - currentQueue = null; - draining = false; - runClearTimeout(timeout); -} - -process.nextTick = function (fun) { - var args = new Array(arguments.length - 1); - if (arguments.length > 1) { - for (var i = 1; i < arguments.length; i++) { - args[i - 1] = arguments[i]; - } - } - queue.push(new Item(fun, args)); - if (queue.length === 1 && !draining) { - runTimeout(drainQueue); - } -}; - -// v8 likes predictible objects -function Item(fun, array) { - this.fun = fun; - this.array = array; -} -Item.prototype.run = function () { - this.fun.apply(null, this.array); -}; -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; -process.version = ''; // empty string to avoid regexp issues -process.versions = {}; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; -process.prependListener = noop; -process.prependOnceListener = noop; - -process.listeners = function (name) { return [] } - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -}; - -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; -process.umask = function() { return 0; }; - -},{}],19:[function(_dereq_,module,exports){ -module.exports = _dereq_(20); - -},{"20":20}],20:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// a duplex stream is just a stream that is both readable and writable. -// Since JS doesn't have multiple prototypal inheritance, this class -// prototypally inherits from Readable, and then parasitically from -// Writable. - -'use strict'; - -/**/ - -var pna = _dereq_(17); -/**/ - -/**/ -var objectKeys = Object.keys || function (obj) { - var keys = []; - for (var key in obj) { - keys.push(key); - }return keys; -}; -/**/ - -module.exports = Duplex; - -/**/ -var util = _dereq_(12); -util.inherits = _dereq_(15); -/**/ - -var Readable = _dereq_(22); -var Writable = _dereq_(24); - -util.inherits(Duplex, Readable); - -{ - // avoid scope creep, the keys array can then be collected - var keys = objectKeys(Writable.prototype); - for (var v = 0; v < keys.length; v++) { - var method = keys[v]; - if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; - } -} - -function Duplex(options) { - if (!(this instanceof Duplex)) return new Duplex(options); - - Readable.call(this, options); - Writable.call(this, options); - - if (options && options.readable === false) this.readable = false; - - if (options && options.writable === false) this.writable = false; - - this.allowHalfOpen = true; - if (options && options.allowHalfOpen === false) this.allowHalfOpen = false; - - this.once('end', onend); -} - -Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function () { - return this._writableState.highWaterMark; - } -}); - -// the no-half-open enforcer -function onend() { - // if we allow half-open state, or if the writable side ended, - // then we're ok. - if (this.allowHalfOpen || this._writableState.ended) return; - - // no more data can be written. - // But allow more writes to happen in this tick. - pna.nextTick(onEndNT, this); -} - -function onEndNT(self) { - self.end(); -} - -Object.defineProperty(Duplex.prototype, 'destroyed', { - get: function () { - if (this._readableState === undefined || this._writableState === undefined) { - return false; - } - return this._readableState.destroyed && this._writableState.destroyed; - }, - set: function (value) { - // we ignore the value if the stream - // has not been initialized yet - if (this._readableState === undefined || this._writableState === undefined) { - return; - } - - // backward compatibility, the user is explicitly - // managing destroyed - this._readableState.destroyed = value; - this._writableState.destroyed = value; - } -}); - -Duplex.prototype._destroy = function (err, cb) { - this.push(null); - this.end(); - - pna.nextTick(cb, err); -}; -},{"12":12,"15":15,"17":17,"22":22,"24":24}],21:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// a passthrough stream. -// basically just the most minimal sort of Transform stream. -// Every written chunk gets output as-is. - -'use strict'; - -module.exports = PassThrough; - -var Transform = _dereq_(23); - -/**/ -var util = _dereq_(12); -util.inherits = _dereq_(15); -/**/ - -util.inherits(PassThrough, Transform); - -function PassThrough(options) { - if (!(this instanceof PassThrough)) return new PassThrough(options); - - Transform.call(this, options); -} - -PassThrough.prototype._transform = function (chunk, encoding, cb) { - cb(null, chunk); -}; -},{"12":12,"15":15,"23":23}],22:[function(_dereq_,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -/**/ - -var pna = _dereq_(17); -/**/ - -module.exports = Readable; - -/**/ -var isArray = _dereq_(28); -/**/ - -/**/ -var Duplex; -/**/ - -Readable.ReadableState = ReadableState; - -/**/ -var EE = _dereq_(13).EventEmitter; - -var EElistenerCount = function (emitter, type) { - return emitter.listeners(type).length; -}; -/**/ - -/**/ -var Stream = _dereq_(27); -/**/ - -/**/ - -var Buffer = _dereq_(34).Buffer; -var OurUint8Array = global.Uint8Array || function () {}; -function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk); -} -function _isUint8Array(obj) { - return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; -} - -/**/ - -/**/ -var util = _dereq_(12); -util.inherits = _dereq_(15); -/**/ - -/**/ -var debugUtil = _dereq_(9); -var debug = void 0; -if (debugUtil && debugUtil.debuglog) { - debug = debugUtil.debuglog('stream'); -} else { - debug = function () {}; -} -/**/ - -var BufferList = _dereq_(25); -var destroyImpl = _dereq_(26); -var StringDecoder; - -util.inherits(Readable, Stream); - -var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; - -function prependListener(emitter, event, fn) { - // Sadly this is not cacheable as some libraries bundle their own - // event emitter implementation with them. - if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); - - // This is a hack to make sure that our error handler is attached before any - // userland ones. NEVER DO THIS. This is here only because this code needs - // to continue to work with older versions of Node.js that do not include - // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; -} - -function ReadableState(options, stream) { - Duplex = Duplex || _dereq_(20); - - options = options || {}; - - // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - var isDuplex = stream instanceof Duplex; - - // object stream flag. Used to make read(n) ignore n and to - // make all the buffer merging and length checks go away - this.objectMode = !!options.objectMode; - - if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; - - // the point at which it stops calling _read() to fill the buffer - // Note: 0 is a valid value, means "don't call _read preemptively ever" - var hwm = options.highWaterMark; - var readableHwm = options.readableHighWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - - if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm; - - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); - - // A linked list is used to store data chunks instead of an array because the - // linked list can remove elements from the beginning faster than - // array.shift() - this.buffer = new BufferList(); - this.length = 0; - this.pipes = null; - this.pipesCount = 0; - this.flowing = null; - this.ended = false; - this.endEmitted = false; - this.reading = false; - - // a flag to be able to tell if the event 'readable'/'data' is emitted - // immediately, or on a later tick. We set this to true at first, because - // any actions that shouldn't happen until "later" should generally also - // not happen before the first read call. - this.sync = true; - - // whenever we return null, then we set a flag to say - // that we're awaiting a 'readable' event emission. - this.needReadable = false; - this.emittedReadable = false; - this.readableListening = false; - this.resumeScheduled = false; - - // has it been destroyed - this.destroyed = false; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // the number of writers that are awaiting a drain event in .pipe()s - this.awaitDrain = 0; - - // if true, a maybeReadMore has been scheduled - this.readingMore = false; - - this.decoder = null; - this.encoding = null; - if (options.encoding) { - if (!StringDecoder) StringDecoder = _dereq_(29).StringDecoder; - this.decoder = new StringDecoder(options.encoding); - this.encoding = options.encoding; - } -} - -function Readable(options) { - Duplex = Duplex || _dereq_(20); - - if (!(this instanceof Readable)) return new Readable(options); - - this._readableState = new ReadableState(options, this); - - // legacy - this.readable = true; - - if (options) { - if (typeof options.read === 'function') this._read = options.read; - - if (typeof options.destroy === 'function') this._destroy = options.destroy; - } - - Stream.call(this); -} - -Object.defineProperty(Readable.prototype, 'destroyed', { - get: function () { - if (this._readableState === undefined) { - return false; - } - return this._readableState.destroyed; - }, - set: function (value) { - // we ignore the value if the stream - // has not been initialized yet - if (!this._readableState) { - return; - } - - // backward compatibility, the user is explicitly - // managing destroyed - this._readableState.destroyed = value; - } -}); - -Readable.prototype.destroy = destroyImpl.destroy; -Readable.prototype._undestroy = destroyImpl.undestroy; -Readable.prototype._destroy = function (err, cb) { - this.push(null); - cb(err); -}; - -// Manually shove something into the read() buffer. -// This returns true if the highWaterMark has not been hit yet, -// similar to how Writable.write() returns true if you should -// write() some more. -Readable.prototype.push = function (chunk, encoding) { - var state = this._readableState; - var skipChunkCheck; - - if (!state.objectMode) { - if (typeof chunk === 'string') { - encoding = encoding || state.defaultEncoding; - if (encoding !== state.encoding) { - chunk = Buffer.from(chunk, encoding); - encoding = ''; - } - skipChunkCheck = true; - } - } else { - skipChunkCheck = true; - } - - return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); -}; - -// Unshift should *always* be something directly out of read() -Readable.prototype.unshift = function (chunk) { - return readableAddChunk(this, chunk, null, true, false); -}; - -function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { - var state = stream._readableState; - if (chunk === null) { - state.reading = false; - onEofChunk(stream, state); - } else { - var er; - if (!skipChunkCheck) er = chunkInvalid(state, chunk); - if (er) { - stream.emit('error', er); - } else if (state.objectMode || chunk && chunk.length > 0) { - if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { - chunk = _uint8ArrayToBuffer(chunk); - } - - if (addToFront) { - if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); - } else if (state.ended) { - stream.emit('error', new Error('stream.push() after EOF')); - } else { - state.reading = false; - if (state.decoder && !encoding) { - chunk = state.decoder.write(chunk); - if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); - } else { - addChunk(stream, state, chunk, false); - } - } - } else if (!addToFront) { - state.reading = false; - } - } - - return needMoreData(state); -} - -function addChunk(stream, state, chunk, addToFront) { - if (state.flowing && state.length === 0 && !state.sync) { - stream.emit('data', chunk); - stream.read(0); - } else { - // update the buffer info. - state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); - - if (state.needReadable) emitReadable(stream); - } - maybeReadMore(stream, state); -} - -function chunkInvalid(state, chunk) { - var er; - if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - return er; -} - -// if it's past the high water mark, we can push in some more. -// Also, if we have no data yet, we can stand some -// more bytes. This is to work around cases where hwm=0, -// such as the repl. Also, if the push() triggered a -// readable event, and the user called read(largeNumber) such that -// needReadable was set, then we ought to push more, so that another -// 'readable' event will be triggered. -function needMoreData(state) { - return !state.ended && (state.needReadable || state.length < state.highWaterMark || state.length === 0); -} - -Readable.prototype.isPaused = function () { - return this._readableState.flowing === false; -}; - -// backwards compatibility. -Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = _dereq_(29).StringDecoder; - this._readableState.decoder = new StringDecoder(enc); - this._readableState.encoding = enc; - return this; -}; - -// Don't raise the hwm > 8MB -var MAX_HWM = 0x800000; -function computeNewHighWaterMark(n) { - if (n >= MAX_HWM) { - n = MAX_HWM; - } else { - // Get the next highest power of 2 to prevent increasing hwm excessively in - // tiny amounts - n--; - n |= n >>> 1; - n |= n >>> 2; - n |= n >>> 4; - n |= n >>> 8; - n |= n >>> 16; - n++; - } - return n; -} - -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function howMuchToRead(n, state) { - if (n <= 0 || state.length === 0 && state.ended) return 0; - if (state.objectMode) return 1; - if (n !== n) { - // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; - } - // If we're asking for more than the current hwm, then raise the hwm. - if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); - if (n <= state.length) return n; - // Don't have enough - if (!state.ended) { - state.needReadable = true; - return 0; - } - return state.length; -} - -// you can override either this method, or the async _read(n) below. -Readable.prototype.read = function (n) { - debug('read', n); - n = parseInt(n, 10); - var state = this._readableState; - var nOrig = n; - - if (n !== 0) state.emittedReadable = false; - - // if we're doing read(0) to trigger a readable event, but we - // already have a bunch of data in the buffer, then just trigger - // the 'readable' event and move on. - if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { - debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); - return null; - } - - n = howMuchToRead(n, state); - - // if we've ended, and we're now clear, then finish it up. - if (n === 0 && state.ended) { - if (state.length === 0) endReadable(this); - return null; - } - - // All the actual chunk generation logic needs to be - // *below* the call to _read. The reason is that in certain - // synthetic stream cases, such as passthrough streams, _read - // may be a completely synchronous operation which may change - // the state of the read buffer, providing enough data when - // before there was *not* enough. - // - // So, the steps are: - // 1. Figure out what the state of things will be after we do - // a read from the buffer. - // - // 2. If that resulting state will trigger a _read, then call _read. - // Note that this may be asynchronous, or synchronous. Yes, it is - // deeply ugly to write APIs this way, but that still doesn't mean - // that the Readable class should behave improperly, as streams are - // designed to be sync/async agnostic. - // Take note if the _read call is sync or async (ie, if the read call - // has returned yet), so that we know whether or not it's safe to emit - // 'readable' etc. - // - // 3. Actually pull the requested chunks out of the buffer and return. - - // if we need a readable event, then we need to do some reading. - var doRead = state.needReadable; - debug('need readable', doRead); - - // if we currently have less than the highWaterMark, then also read some - if (state.length === 0 || state.length - n < state.highWaterMark) { - doRead = true; - debug('length less than watermark', doRead); - } - - // however, if we've ended, then there's no point, and if we're already - // reading, then it's unnecessary. - if (state.ended || state.reading) { - doRead = false; - debug('reading or ended', doRead); - } else if (doRead) { - debug('do read'); - state.reading = true; - state.sync = true; - // if the length is currently zero, then we *need* a readable event. - if (state.length === 0) state.needReadable = true; - // call internal read method - this._read(state.highWaterMark); - state.sync = false; - // If _read pushed data synchronously, then `reading` will be false, - // and we need to re-evaluate how much data we can return to the user. - if (!state.reading) n = howMuchToRead(nOrig, state); - } - - var ret; - if (n > 0) ret = fromList(n, state);else ret = null; - - if (ret === null) { - state.needReadable = true; - n = 0; - } else { - state.length -= n; - } - - if (state.length === 0) { - // If we have nothing in the buffer, then we want to know - // as soon as we *do* get something into the buffer. - if (!state.ended) state.needReadable = true; - - // If we tried to read() past the EOF, then emit end on the next tick. - if (nOrig !== n && state.ended) endReadable(this); - } - - if (ret !== null) this.emit('data', ret); - - return ret; -}; - -function onEofChunk(stream, state) { - if (state.ended) return; - if (state.decoder) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) { - state.buffer.push(chunk); - state.length += state.objectMode ? 1 : chunk.length; - } - } - state.ended = true; - - // emit 'readable' now to make sure it gets picked up. - emitReadable(stream); -} - -// Don't emit readable right away in sync mode, because this can trigger -// another read() call => stack overflow. This way, it might trigger -// a nextTick recursion warning, but that's not so bad. -function emitReadable(stream) { - var state = stream._readableState; - state.needReadable = false; - if (!state.emittedReadable) { - debug('emitReadable', state.flowing); - state.emittedReadable = true; - if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream); - } -} - -function emitReadable_(stream) { - debug('emit readable'); - stream.emit('readable'); - flow(stream); -} - -// at this point, the user has presumably seen the 'readable' event, -// and called read() to consume some data. that may have triggered -// in turn another _read(n) call, in which case reading = true if -// it's in progress. -// However, if we're not ended, or reading, and the length < hwm, -// then go ahead and try to read some more preemptively. -function maybeReadMore(stream, state) { - if (!state.readingMore) { - state.readingMore = true; - pna.nextTick(maybeReadMore_, stream, state); - } -} - -function maybeReadMore_(stream, state) { - var len = state.length; - while (!state.reading && !state.flowing && !state.ended && state.length < state.highWaterMark) { - debug('maybeReadMore read 0'); - stream.read(0); - if (len === state.length) - // didn't get any data, stop spinning. - break;else len = state.length; - } - state.readingMore = false; -} - -// abstract method. to be overridden in specific implementation classes. -// call cb(er, data) where data is <= n in length. -// for virtual (non-string, non-buffer) streams, "length" is somewhat -// arbitrary, and perhaps not very meaningful. -Readable.prototype._read = function (n) { - this.emit('error', new Error('_read() is not implemented')); -}; - -Readable.prototype.pipe = function (dest, pipeOpts) { - var src = this; - var state = this._readableState; - - switch (state.pipesCount) { - case 0: - state.pipes = dest; - break; - case 1: - state.pipes = [state.pipes, dest]; - break; - default: - state.pipes.push(dest); - break; - } - state.pipesCount += 1; - debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); - - var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - - var endFn = doEnd ? onend : unpipe; - if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn); - - dest.on('unpipe', onunpipe); - function onunpipe(readable, unpipeInfo) { - debug('onunpipe'); - if (readable === src) { - if (unpipeInfo && unpipeInfo.hasUnpiped === false) { - unpipeInfo.hasUnpiped = true; - cleanup(); - } - } - } - - function onend() { - debug('onend'); - dest.end(); - } - - // when the dest drains, it reduces the awaitDrain counter - // on the source. This would be more elegant with a .once() - // handler in flow(), but adding and removing repeatedly is - // too slow. - var ondrain = pipeOnDrain(src); - dest.on('drain', ondrain); - - var cleanedUp = false; - function cleanup() { - debug('cleanup'); - // cleanup event handlers once the pipe is broken - dest.removeListener('close', onclose); - dest.removeListener('finish', onfinish); - dest.removeListener('drain', ondrain); - dest.removeListener('error', onerror); - dest.removeListener('unpipe', onunpipe); - src.removeListener('end', onend); - src.removeListener('end', unpipe); - src.removeListener('data', ondata); - - cleanedUp = true; - - // if the reader is waiting for a drain event from this - // specific writer, then it would cause it to never start - // flowing again. - // So, if this is awaiting a drain, then we just call it now. - // If we don't know, then assume that we are waiting for one. - if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); - } - - // If the user pushes more data while we're writing to dest then we'll end up - // in ondata again. However, we only want to increase awaitDrain once because - // dest will only emit one 'drain' event for the multiple writes. - // => Introduce a guard on increasing awaitDrain. - var increasedAwaitDrain = false; - src.on('data', ondata); - function ondata(chunk) { - debug('ondata'); - increasedAwaitDrain = false; - var ret = dest.write(chunk); - if (false === ret && !increasedAwaitDrain) { - // If the user unpiped during `dest.write()`, it is possible - // to get stuck in a permanently paused state if that write - // also returned false. - // => Check whether `dest` is still a piping destination. - if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { - debug('false write response, pause', src._readableState.awaitDrain); - src._readableState.awaitDrain++; - increasedAwaitDrain = true; - } - src.pause(); - } - } - - // if the dest has an error, then stop piping into it. - // however, don't suppress the throwing behavior for this. - function onerror(er) { - debug('onerror', er); - unpipe(); - dest.removeListener('error', onerror); - if (EElistenerCount(dest, 'error') === 0) dest.emit('error', er); - } - - // Make sure our error handler is attached before userland ones. - prependListener(dest, 'error', onerror); - - // Both close and finish should trigger unpipe, but only once. - function onclose() { - dest.removeListener('finish', onfinish); - unpipe(); - } - dest.once('close', onclose); - function onfinish() { - debug('onfinish'); - dest.removeListener('close', onclose); - unpipe(); - } - dest.once('finish', onfinish); - - function unpipe() { - debug('unpipe'); - src.unpipe(dest); - } - - // tell the dest that it's being piped to - dest.emit('pipe', src); - - // start the flow if it hasn't been started already. - if (!state.flowing) { - debug('pipe resume'); - src.resume(); - } - - return dest; -}; - -function pipeOnDrain(src) { - return function () { - var state = src._readableState; - debug('pipeOnDrain', state.awaitDrain); - if (state.awaitDrain) state.awaitDrain--; - if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { - state.flowing = true; - flow(src); - } - }; -} - -Readable.prototype.unpipe = function (dest) { - var state = this._readableState; - var unpipeInfo = { hasUnpiped: false }; - - // if we're not piping anywhere, then do nothing. - if (state.pipesCount === 0) return this; - - // just one destination. most common case. - if (state.pipesCount === 1) { - // passed in one, but it's not the right one. - if (dest && dest !== state.pipes) return this; - - if (!dest) dest = state.pipes; - - // got a match. - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - if (dest) dest.emit('unpipe', this, unpipeInfo); - return this; - } - - // slow case. multiple pipe destinations. - - if (!dest) { - // remove all. - var dests = state.pipes; - var len = state.pipesCount; - state.pipes = null; - state.pipesCount = 0; - state.flowing = false; - - for (var i = 0; i < len; i++) { - dests[i].emit('unpipe', this, unpipeInfo); - }return this; - } - - // try to find the right one. - var index = indexOf(state.pipes, dest); - if (index === -1) return this; - - state.pipes.splice(index, 1); - state.pipesCount -= 1; - if (state.pipesCount === 1) state.pipes = state.pipes[0]; - - dest.emit('unpipe', this, unpipeInfo); - - return this; -}; - -// set up data events if they are asked for -// Ensure readable listeners eventually get something -Readable.prototype.on = function (ev, fn) { - var res = Stream.prototype.on.call(this, ev, fn); - - if (ev === 'data') { - // Start flowing on next tick if stream isn't explicitly paused - if (this._readableState.flowing !== false) this.resume(); - } else if (ev === 'readable') { - var state = this._readableState; - if (!state.endEmitted && !state.readableListening) { - state.readableListening = state.needReadable = true; - state.emittedReadable = false; - if (!state.reading) { - pna.nextTick(nReadingNextTick, this); - } else if (state.length) { - emitReadable(this); - } - } - } - - return res; -}; -Readable.prototype.addListener = Readable.prototype.on; - -function nReadingNextTick(self) { - debug('readable nexttick read 0'); - self.read(0); -} - -// pause() and resume() are remnants of the legacy readable stream API -// If the user uses them, then switch into old mode. -Readable.prototype.resume = function () { - var state = this._readableState; - if (!state.flowing) { - debug('resume'); - state.flowing = true; - resume(this, state); - } - return this; -}; - -function resume(stream, state) { - if (!state.resumeScheduled) { - state.resumeScheduled = true; - pna.nextTick(resume_, stream, state); - } -} - -function resume_(stream, state) { - if (!state.reading) { - debug('resume read 0'); - stream.read(0); - } - - state.resumeScheduled = false; - state.awaitDrain = 0; - stream.emit('resume'); - flow(stream); - if (state.flowing && !state.reading) stream.read(0); -} - -Readable.prototype.pause = function () { - debug('call pause flowing=%j', this._readableState.flowing); - if (false !== this._readableState.flowing) { - debug('pause'); - this._readableState.flowing = false; - this.emit('pause'); - } - return this; -}; - -function flow(stream) { - var state = stream._readableState; - debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) {} -} - -// wrap an old-style stream as the async data source. -// This is *not* part of the readable stream interface. -// It is an ugly unfortunate mess of history. -Readable.prototype.wrap = function (stream) { - var _this = this; - - var state = this._readableState; - var paused = false; - - stream.on('end', function () { - debug('wrapped end'); - if (state.decoder && !state.ended) { - var chunk = state.decoder.end(); - if (chunk && chunk.length) _this.push(chunk); - } - - _this.push(null); - }); - - stream.on('data', function (chunk) { - debug('wrapped data'); - if (state.decoder) chunk = state.decoder.write(chunk); - - // don't skip over falsy values in objectMode - if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; - - var ret = _this.push(chunk); - if (!ret) { - paused = true; - stream.pause(); - } - }); - - // proxy all the other methods. - // important when wrapping filters and duplexes. - for (var i in stream) { - if (this[i] === undefined && typeof stream[i] === 'function') { - this[i] = function (method) { - return function () { - return stream[method].apply(stream, arguments); - }; - }(i); - } - } - - // proxy certain important events. - for (var n = 0; n < kProxyEvents.length; n++) { - stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); - } - - // when we try to consume some more bytes, simply unpause the - // underlying stream. - this._read = function (n) { - debug('wrapped _read', n); - if (paused) { - paused = false; - stream.resume(); - } - }; - - return this; -}; - -Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function () { - return this._readableState.highWaterMark; - } -}); - -// exposed for testing purposes only. -Readable._fromList = fromList; - -// Pluck off n bytes from an array of buffers. -// Length is the combined lengths of all the buffers in the list. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromList(n, state) { - // nothing buffered - if (state.length === 0) return null; - - var ret; - if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { - // read it all, truncate the list - if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); - state.buffer.clear(); - } else { - // read part of list - ret = fromListPartial(n, state.buffer, state.decoder); - } - - return ret; -} - -// Extracts only enough buffered data to satisfy the amount requested. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function fromListPartial(n, list, hasStrings) { - var ret; - if (n < list.head.data.length) { - // slice is the same for buffers and strings - ret = list.head.data.slice(0, n); - list.head.data = list.head.data.slice(n); - } else if (n === list.head.data.length) { - // first chunk is a perfect match - ret = list.shift(); - } else { - // result spans more than one buffer - ret = hasStrings ? copyFromBufferString(n, list) : copyFromBuffer(n, list); - } - return ret; -} - -// Copies a specified amount of characters from the list of buffered data -// chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBufferString(n, list) { - var p = list.head; - var c = 1; - var ret = p.data; - n -= ret.length; - while (p = p.next) { - var str = p.data; - var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str;else ret += str.slice(0, n); - n -= nb; - if (n === 0) { - if (nb === str.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = str.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -// Copies a specified amount of bytes from the list of buffered data chunks. -// This function is designed to be inlinable, so please take care when making -// changes to the function body. -function copyFromBuffer(n, list) { - var ret = Buffer.allocUnsafe(n); - var p = list.head; - var c = 1; - p.data.copy(ret); - n -= p.data.length; - while (p = p.next) { - var buf = p.data; - var nb = n > buf.length ? buf.length : n; - buf.copy(ret, ret.length - n, 0, nb); - n -= nb; - if (n === 0) { - if (nb === buf.length) { - ++c; - if (p.next) list.head = p.next;else list.head = list.tail = null; - } else { - list.head = p; - p.data = buf.slice(nb); - } - break; - } - ++c; - } - list.length -= c; - return ret; -} - -function endReadable(stream) { - var state = stream._readableState; - - // If we get here before consuming all the bytes, then that is a - // bug in node. Should never happen. - if (state.length > 0) throw new Error('"endReadable()" called on non-empty stream'); - - if (!state.endEmitted) { - state.ended = true; - pna.nextTick(endReadableNT, state, stream); - } -} - -function endReadableNT(state, stream) { - // Check that we didn't get one last unshift. - if (!state.endEmitted && state.length === 0) { - state.endEmitted = true; - stream.readable = false; - stream.emit('end'); - } -} - -function indexOf(xs, x) { - for (var i = 0, l = xs.length; i < l; i++) { - if (xs[i] === x) return i; - } - return -1; -} -}).call(this,_dereq_(18),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"12":12,"13":13,"15":15,"17":17,"18":18,"20":20,"25":25,"26":26,"27":27,"28":28,"29":29,"34":34,"9":9}],23:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// a transform stream is a readable/writable stream where you do -// something with the data. Sometimes it's called a "filter", -// but that's not a great name for it, since that implies a thing where -// some bits pass through, and others are simply ignored. (That would -// be a valid example of a transform, of course.) -// -// While the output is causally related to the input, it's not a -// necessarily symmetric or synchronous transformation. For example, -// a zlib stream might take multiple plain-text writes(), and then -// emit a single compressed chunk some time in the future. -// -// Here's how this works: -// -// The Transform stream has all the aspects of the readable and writable -// stream classes. When you write(chunk), that calls _write(chunk,cb) -// internally, and returns false if there's a lot of pending writes -// buffered up. When you call read(), that calls _read(n) until -// there's enough pending readable data buffered up. -// -// In a transform stream, the written data is placed in a buffer. When -// _read(n) is called, it transforms the queued up data, calling the -// buffered _write cb's as it consumes chunks. If consuming a single -// written chunk would result in multiple output chunks, then the first -// outputted bit calls the readcb, and subsequent chunks just go into -// the read buffer, and will cause it to emit 'readable' if necessary. -// -// This way, back-pressure is actually determined by the reading side, -// since _read has to be called to start processing a new chunk. However, -// a pathological inflate type of transform can cause excessive buffering -// here. For example, imagine a stream where every byte of input is -// interpreted as an integer from 0-255, and then results in that many -// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in -// 1kb of data being output. In this case, you could write a very small -// amount of input, and end up with a very large amount of output. In -// such a pathological inflating mechanism, there'd be no way to tell -// the system to stop doing the transform. A single 4MB write could -// cause the system to run out of memory. -// -// However, even in such a pathological case, only a single written chunk -// would be consumed, and then the rest would wait (un-transformed) until -// the results of the previous transformed chunk were consumed. - -'use strict'; - -module.exports = Transform; - -var Duplex = _dereq_(20); - -/**/ -var util = _dereq_(12); -util.inherits = _dereq_(15); -/**/ - -util.inherits(Transform, Duplex); - -function afterTransform(er, data) { - var ts = this._transformState; - ts.transforming = false; - - var cb = ts.writecb; - - if (!cb) { - return this.emit('error', new Error('write callback called multiple times')); - } - - ts.writechunk = null; - ts.writecb = null; - - if (data != null) // single equals check for both `null` and `undefined` - this.push(data); - - cb(er); - - var rs = this._readableState; - rs.reading = false; - if (rs.needReadable || rs.length < rs.highWaterMark) { - this._read(rs.highWaterMark); - } -} - -function Transform(options) { - if (!(this instanceof Transform)) return new Transform(options); - - Duplex.call(this, options); - - this._transformState = { - afterTransform: afterTransform.bind(this), - needTransform: false, - transforming: false, - writecb: null, - writechunk: null, - writeencoding: null - }; - - // start out asking for a readable event once data is transformed. - this._readableState.needReadable = true; - - // we have implemented the _read method, and done the other things - // that Readable wants before the first _read call, so unset the - // sync guard flag. - this._readableState.sync = false; - - if (options) { - if (typeof options.transform === 'function') this._transform = options.transform; - - if (typeof options.flush === 'function') this._flush = options.flush; - } - - // When the writable side finishes, then flush out anything remaining. - this.on('prefinish', prefinish); -} - -function prefinish() { - var _this = this; - - if (typeof this._flush === 'function') { - this._flush(function (er, data) { - done(_this, er, data); - }); - } else { - done(this, null, null); - } -} - -Transform.prototype.push = function (chunk, encoding) { - this._transformState.needTransform = false; - return Duplex.prototype.push.call(this, chunk, encoding); -}; - -// This is the part where you do stuff! -// override this function in implementation classes. -// 'chunk' is an input chunk. -// -// Call `push(newChunk)` to pass along transformed output -// to the readable side. You may call 'push' zero or more times. -// -// Call `cb(err)` when you are done with this chunk. If you pass -// an error, then that'll put the hurt on the whole operation. If you -// never call cb(), then you'll never get another chunk. -Transform.prototype._transform = function (chunk, encoding, cb) { - throw new Error('_transform() is not implemented'); -}; - -Transform.prototype._write = function (chunk, encoding, cb) { - var ts = this._transformState; - ts.writecb = cb; - ts.writechunk = chunk; - ts.writeencoding = encoding; - if (!ts.transforming) { - var rs = this._readableState; - if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); - } -}; - -// Doesn't matter what the args are here. -// _transform does all the work. -// That we got here means that the readable side wants more data. -Transform.prototype._read = function (n) { - var ts = this._transformState; - - if (ts.writechunk !== null && ts.writecb && !ts.transforming) { - ts.transforming = true; - this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); - } else { - // mark that we need a transform, so that any data that comes in - // will get processed, now that we've asked for it. - ts.needTransform = true; - } -}; - -Transform.prototype._destroy = function (err, cb) { - var _this2 = this; - - Duplex.prototype._destroy.call(this, err, function (err2) { - cb(err2); - _this2.emit('close'); - }); -}; - -function done(stream, er, data) { - if (er) return stream.emit('error', er); - - if (data != null) // single equals check for both `null` and `undefined` - stream.push(data); - - // if there's nothing in the write buffer, then that means - // that nothing more will ever be provided - if (stream._writableState.length) throw new Error('Calling transform done when ws.length != 0'); - - if (stream._transformState.transforming) throw new Error('Calling transform done when still transforming'); - - return stream.push(null); -} -},{"12":12,"15":15,"20":20}],24:[function(_dereq_,module,exports){ -(function (process,global){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// A bit simpler than readable streams. -// Implement an async ._write(chunk, encoding, cb), and it'll handle all -// the drain event emission and buffering. - -'use strict'; - -/**/ - -var pna = _dereq_(17); -/**/ - -module.exports = Writable; - -/* */ -function WriteReq(chunk, encoding, cb) { - this.chunk = chunk; - this.encoding = encoding; - this.callback = cb; - this.next = null; -} - -// It seems a linked list but it is not -// there will be only 2 of these for each stream -function CorkedRequest(state) { - var _this = this; - - this.next = null; - this.entry = null; - this.finish = function () { - onCorkedFinish(_this, state); - }; -} -/* */ - -/**/ -var asyncWrite = !process.browser && ['v0.10', 'v0.9.'].indexOf(process.version.slice(0, 5)) > -1 ? setImmediate : pna.nextTick; -/**/ - -/**/ -var Duplex; -/**/ - -Writable.WritableState = WritableState; - -/**/ -var util = _dereq_(12); -util.inherits = _dereq_(15); -/**/ - -/**/ -var internalUtil = { - deprecate: _dereq_(37) -}; -/**/ - -/**/ -var Stream = _dereq_(27); -/**/ - -/**/ - -var Buffer = _dereq_(34).Buffer; -var OurUint8Array = global.Uint8Array || function () {}; -function _uint8ArrayToBuffer(chunk) { - return Buffer.from(chunk); -} -function _isUint8Array(obj) { - return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; -} - -/**/ - -var destroyImpl = _dereq_(26); - -util.inherits(Writable, Stream); - -function nop() {} - -function WritableState(options, stream) { - Duplex = Duplex || _dereq_(20); - - options = options || {}; - - // Duplex streams are both readable and writable, but share - // the same options object. - // However, some cases require setting options to different - // values for the readable and the writable sides of the duplex stream. - // These options can be provided separately as readableXXX and writableXXX. - var isDuplex = stream instanceof Duplex; - - // object stream flag to indicate whether or not this stream - // contains buffers or objects. - this.objectMode = !!options.objectMode; - - if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; - - // the point at which write() starts returning false - // Note: 0 is a valid value, means that we always return false if - // the entire buffer is not flushed immediately on write() - var hwm = options.highWaterMark; - var writableHwm = options.writableHighWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - - if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm; - - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); - - // if _final has been called - this.finalCalled = false; - - // drain event flag. - this.needDrain = false; - // at the start of calling end() - this.ending = false; - // when end() has been called, and returned - this.ended = false; - // when 'finish' is emitted - this.finished = false; - - // has it been destroyed - this.destroyed = false; - - // should we decode strings into buffers before passing to _write? - // this is here so that some node-core streams can optimize string - // handling at a lower level. - var noDecode = options.decodeStrings === false; - this.decodeStrings = !noDecode; - - // Crypto is kind of old and crusty. Historically, its default string - // encoding is 'binary' so we have to make this configurable. - // Everything else in the universe uses 'utf8', though. - this.defaultEncoding = options.defaultEncoding || 'utf8'; - - // not an actual buffer we keep track of, but a measurement - // of how much we're waiting to get pushed to some underlying - // socket or file. - this.length = 0; - - // a flag to see when we're in the middle of a write. - this.writing = false; - - // when true all writes will be buffered until .uncork() call - this.corked = 0; - - // a flag to be able to tell if the onwrite cb is called immediately, - // or on a later tick. We set this to true at first, because any - // actions that shouldn't happen until "later" should generally also - // not happen before the first write call. - this.sync = true; - - // a flag to know if we're processing previously buffered items, which - // may call the _write() callback in the same tick, so that we don't - // end up in an overlapped onwrite situation. - this.bufferProcessing = false; - - // the callback that's passed to _write(chunk,cb) - this.onwrite = function (er) { - onwrite(stream, er); - }; - - // the callback that the user supplies to write(chunk,encoding,cb) - this.writecb = null; - - // the amount that is being written when _write is called. - this.writelen = 0; - - this.bufferedRequest = null; - this.lastBufferedRequest = null; - - // number of pending user-supplied write callbacks - // this must be 0 before 'finish' can be emitted - this.pendingcb = 0; - - // emit prefinish if the only thing we're waiting for is _write cbs - // This is relevant for synchronous Transform streams - this.prefinished = false; - - // True if the error was already emitted and should not be thrown again - this.errorEmitted = false; - - // count buffered requests - this.bufferedRequestCount = 0; - - // allocate the first CorkedRequest, there is always - // one allocated and free to use, and we maintain at most two - this.corkedRequestsFree = new CorkedRequest(this); -} - -WritableState.prototype.getBuffer = function getBuffer() { - var current = this.bufferedRequest; - var out = []; - while (current) { - out.push(current); - current = current.next; - } - return out; -}; - -(function () { - try { - Object.defineProperty(WritableState.prototype, 'buffer', { - get: internalUtil.deprecate(function () { - return this.getBuffer(); - }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') - }); - } catch (_) {} -})(); - -// Test _writableState for inheritance to account for Duplex streams, -// whose prototype chain only points to Readable. -var realHasInstance; -if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { - realHasInstance = Function.prototype[Symbol.hasInstance]; - Object.defineProperty(Writable, Symbol.hasInstance, { - value: function (object) { - if (realHasInstance.call(this, object)) return true; - if (this !== Writable) return false; - - return object && object._writableState instanceof WritableState; - } - }); -} else { - realHasInstance = function (object) { - return object instanceof this; - }; -} - -function Writable(options) { - Duplex = Duplex || _dereq_(20); - - // Writable ctor is applied to Duplexes, too. - // `realHasInstance` is necessary because using plain `instanceof` - // would return false, as no `_writableState` property is attached. - - // Trying to use the custom `instanceof` for Writable here will also break the - // Node.js LazyTransform implementation, which has a non-trivial getter for - // `_writableState` that would lead to infinite recursion. - if (!realHasInstance.call(Writable, this) && !(this instanceof Duplex)) { - return new Writable(options); - } - - this._writableState = new WritableState(options, this); - - // legacy. - this.writable = true; - - if (options) { - if (typeof options.write === 'function') this._write = options.write; - - if (typeof options.writev === 'function') this._writev = options.writev; - - if (typeof options.destroy === 'function') this._destroy = options.destroy; - - if (typeof options.final === 'function') this._final = options.final; - } - - Stream.call(this); -} - -// Otherwise people can pipe Writable streams, which is just wrong. -Writable.prototype.pipe = function () { - this.emit('error', new Error('Cannot pipe, not readable')); -}; - -function writeAfterEnd(stream, cb) { - var er = new Error('write after end'); - // TODO: defer error events consistently everywhere, not just the cb - stream.emit('error', er); - pna.nextTick(cb, er); -} - -// Checks that a user-supplied chunk is valid, especially for the particular -// mode the stream is in. Currently this means that `null` is never accepted -// and undefined/non-string values are only allowed in object mode. -function validChunk(stream, state, chunk, cb) { - var valid = true; - var er = false; - - if (chunk === null) { - er = new TypeError('May not write null values to stream'); - } else if (typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { - er = new TypeError('Invalid non-string/buffer chunk'); - } - if (er) { - stream.emit('error', er); - pna.nextTick(cb, er); - valid = false; - } - return valid; -} - -Writable.prototype.write = function (chunk, encoding, cb) { - var state = this._writableState; - var ret = false; - var isBuf = !state.objectMode && _isUint8Array(chunk); - - if (isBuf && !Buffer.isBuffer(chunk)) { - chunk = _uint8ArrayToBuffer(chunk); - } - - if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; - - if (typeof cb !== 'function') cb = nop; - - if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { - state.pendingcb++; - ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); - } - - return ret; -}; - -Writable.prototype.cork = function () { - var state = this._writableState; - - state.corked++; -}; - -Writable.prototype.uncork = function () { - var state = this._writableState; - - if (state.corked) { - state.corked--; - - if (!state.writing && !state.corked && !state.finished && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); - } -}; - -Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { - // node::ParseEncoding() requires lower case. - if (typeof encoding === 'string') encoding = encoding.toLowerCase(); - if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new TypeError('Unknown encoding: ' + encoding); - this._writableState.defaultEncoding = encoding; - return this; -}; - -function decodeChunk(state, chunk, encoding) { - if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = Buffer.from(chunk, encoding); - } - return chunk; -} - -Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { - // making it explicit this property is not enumerable - // because otherwise some prototype manipulation in - // userland will fail - enumerable: false, - get: function () { - return this._writableState.highWaterMark; - } -}); - -// if we're already writing something, then just put this -// in the queue, and wait our turn. Otherwise, call _write -// If we return false, then we need a drain event, so set that flag. -function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { - if (!isBuf) { - var newChunk = decodeChunk(state, chunk, encoding); - if (chunk !== newChunk) { - isBuf = true; - encoding = 'buffer'; - chunk = newChunk; - } - } - var len = state.objectMode ? 1 : chunk.length; - - state.length += len; - - var ret = state.length < state.highWaterMark; - // we must ensure that previous needDrain will not be reset to false. - if (!ret) state.needDrain = true; - - if (state.writing || state.corked) { - var last = state.lastBufferedRequest; - state.lastBufferedRequest = { - chunk: chunk, - encoding: encoding, - isBuf: isBuf, - callback: cb, - next: null - }; - if (last) { - last.next = state.lastBufferedRequest; - } else { - state.bufferedRequest = state.lastBufferedRequest; - } - state.bufferedRequestCount += 1; - } else { - doWrite(stream, state, false, len, chunk, encoding, cb); - } - - return ret; -} - -function doWrite(stream, state, writev, len, chunk, encoding, cb) { - state.writelen = len; - state.writecb = cb; - state.writing = true; - state.sync = true; - if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); - state.sync = false; -} - -function onwriteError(stream, state, sync, er, cb) { - --state.pendingcb; - - if (sync) { - // defer the callback if we are being called synchronously - // to avoid piling up things on the stack - pna.nextTick(cb, er); - // this can emit finish, and it will always happen - // after error - pna.nextTick(finishMaybe, stream, state); - stream._writableState.errorEmitted = true; - stream.emit('error', er); - } else { - // the caller expect this to happen before if - // it is async - cb(er); - stream._writableState.errorEmitted = true; - stream.emit('error', er); - // this can emit finish, but finish must - // always follow error - finishMaybe(stream, state); - } -} - -function onwriteStateUpdate(state) { - state.writing = false; - state.writecb = null; - state.length -= state.writelen; - state.writelen = 0; -} - -function onwrite(stream, er) { - var state = stream._writableState; - var sync = state.sync; - var cb = state.writecb; - - onwriteStateUpdate(state); - - if (er) onwriteError(stream, state, sync, er, cb);else { - // Check if we're actually ready to finish, but don't emit yet - var finished = needFinish(state); - - if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { - clearBuffer(stream, state); - } - - if (sync) { - /**/ - asyncWrite(afterWrite, stream, state, finished, cb); - /**/ - } else { - afterWrite(stream, state, finished, cb); - } - } -} - -function afterWrite(stream, state, finished, cb) { - if (!finished) onwriteDrain(stream, state); - state.pendingcb--; - cb(); - finishMaybe(stream, state); -} - -// Must force callback to be called on nextTick, so that we don't -// emit 'drain' before the write() consumer gets the 'false' return -// value, and has a chance to attach a 'drain' listener. -function onwriteDrain(stream, state) { - if (state.length === 0 && state.needDrain) { - state.needDrain = false; - stream.emit('drain'); - } -} - -// if there's something in the buffer waiting, then process it -function clearBuffer(stream, state) { - state.bufferProcessing = true; - var entry = state.bufferedRequest; - - if (stream._writev && entry && entry.next) { - // Fast case, write everything using _writev() - var l = state.bufferedRequestCount; - var buffer = new Array(l); - var holder = state.corkedRequestsFree; - holder.entry = entry; - - var count = 0; - var allBuffers = true; - while (entry) { - buffer[count] = entry; - if (!entry.isBuf) allBuffers = false; - entry = entry.next; - count += 1; - } - buffer.allBuffers = allBuffers; - - doWrite(stream, state, true, state.length, buffer, '', holder.finish); - - // doWrite is almost always async, defer these to save a bit of time - // as the hot path ends with doWrite - state.pendingcb++; - state.lastBufferedRequest = null; - if (holder.next) { - state.corkedRequestsFree = holder.next; - holder.next = null; - } else { - state.corkedRequestsFree = new CorkedRequest(state); - } - state.bufferedRequestCount = 0; - } else { - // Slow case, write chunks one-by-one - while (entry) { - var chunk = entry.chunk; - var encoding = entry.encoding; - var cb = entry.callback; - var len = state.objectMode ? 1 : chunk.length; - - doWrite(stream, state, false, len, chunk, encoding, cb); - entry = entry.next; - state.bufferedRequestCount--; - // if we didn't call the onwrite immediately, then - // it means that we need to wait until it does. - // also, that means that the chunk and cb are currently - // being processed, so move the buffer counter past them. - if (state.writing) { - break; - } - } - - if (entry === null) state.lastBufferedRequest = null; - } - - state.bufferedRequest = entry; - state.bufferProcessing = false; -} - -Writable.prototype._write = function (chunk, encoding, cb) { - cb(new Error('_write() is not implemented')); -}; - -Writable.prototype._writev = null; - -Writable.prototype.end = function (chunk, encoding, cb) { - var state = this._writableState; - - if (typeof chunk === 'function') { - cb = chunk; - chunk = null; - encoding = null; - } else if (typeof encoding === 'function') { - cb = encoding; - encoding = null; - } - - if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); - - // .end() fully uncorks - if (state.corked) { - state.corked = 1; - this.uncork(); - } - - // ignore unnecessary end() calls. - if (!state.ending && !state.finished) endWritable(this, state, cb); -}; - -function needFinish(state) { - return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; -} -function callFinal(stream, state) { - stream._final(function (err) { - state.pendingcb--; - if (err) { - stream.emit('error', err); - } - state.prefinished = true; - stream.emit('prefinish'); - finishMaybe(stream, state); - }); -} -function prefinish(stream, state) { - if (!state.prefinished && !state.finalCalled) { - if (typeof stream._final === 'function') { - state.pendingcb++; - state.finalCalled = true; - pna.nextTick(callFinal, stream, state); - } else { - state.prefinished = true; - stream.emit('prefinish'); - } - } -} - -function finishMaybe(stream, state) { - var need = needFinish(state); - if (need) { - prefinish(stream, state); - if (state.pendingcb === 0) { - state.finished = true; - stream.emit('finish'); - } - } - return need; -} - -function endWritable(stream, state, cb) { - state.ending = true; - finishMaybe(stream, state); - if (cb) { - if (state.finished) pna.nextTick(cb);else stream.once('finish', cb); - } - state.ended = true; - stream.writable = false; -} - -function onCorkedFinish(corkReq, state, err) { - var entry = corkReq.entry; - corkReq.entry = null; - while (entry) { - var cb = entry.callback; - state.pendingcb--; - cb(err); - entry = entry.next; - } - if (state.corkedRequestsFree) { - state.corkedRequestsFree.next = corkReq; - } else { - state.corkedRequestsFree = corkReq; - } -} - -Object.defineProperty(Writable.prototype, 'destroyed', { - get: function () { - if (this._writableState === undefined) { - return false; - } - return this._writableState.destroyed; - }, - set: function (value) { - // we ignore the value if the stream - // has not been initialized yet - if (!this._writableState) { - return; - } - - // backward compatibility, the user is explicitly - // managing destroyed - this._writableState.destroyed = value; - } -}); - -Writable.prototype.destroy = destroyImpl.destroy; -Writable.prototype._undestroy = destroyImpl.undestroy; -Writable.prototype._destroy = function (err, cb) { - this.end(); - cb(err); -}; -}).call(this,_dereq_(18),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{"12":12,"15":15,"17":17,"18":18,"20":20,"26":26,"27":27,"34":34,"37":37}],25:[function(_dereq_,module,exports){ -'use strict'; - -function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - -var Buffer = _dereq_(34).Buffer; -var util = _dereq_(9); - -function copyBuffer(src, target, offset) { - src.copy(target, offset); -} - -module.exports = function () { - function BufferList() { - _classCallCheck(this, BufferList); - - this.head = null; - this.tail = null; - this.length = 0; - } - - BufferList.prototype.push = function push(v) { - var entry = { data: v, next: null }; - if (this.length > 0) this.tail.next = entry;else this.head = entry; - this.tail = entry; - ++this.length; - }; - - BufferList.prototype.unshift = function unshift(v) { - var entry = { data: v, next: this.head }; - if (this.length === 0) this.tail = entry; - this.head = entry; - ++this.length; - }; - - BufferList.prototype.shift = function shift() { - if (this.length === 0) return; - var ret = this.head.data; - if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; - --this.length; - return ret; - }; - - BufferList.prototype.clear = function clear() { - this.head = this.tail = null; - this.length = 0; - }; - - BufferList.prototype.join = function join(s) { - if (this.length === 0) return ''; - var p = this.head; - var ret = '' + p.data; - while (p = p.next) { - ret += s + p.data; - }return ret; - }; - - BufferList.prototype.concat = function concat(n) { - if (this.length === 0) return Buffer.alloc(0); - if (this.length === 1) return this.head.data; - var ret = Buffer.allocUnsafe(n >>> 0); - var p = this.head; - var i = 0; - while (p) { - copyBuffer(p.data, ret, i); - i += p.data.length; - p = p.next; - } - return ret; - }; - - return BufferList; -}(); - -if (util && util.inspect && util.inspect.custom) { - module.exports.prototype[util.inspect.custom] = function () { - var obj = util.inspect({ length: this.length }); - return this.constructor.name + ' ' + obj; - }; -} -},{"34":34,"9":9}],26:[function(_dereq_,module,exports){ -'use strict'; - -/**/ - -var pna = _dereq_(17); -/**/ - -// undocumented cb() API, needed for core, not for public API -function destroy(err, cb) { - var _this = this; - - var readableDestroyed = this._readableState && this._readableState.destroyed; - var writableDestroyed = this._writableState && this._writableState.destroyed; - - if (readableDestroyed || writableDestroyed) { - if (cb) { - cb(err); - } else if (err && (!this._writableState || !this._writableState.errorEmitted)) { - pna.nextTick(emitErrorNT, this, err); - } - return this; - } - - // we set destroyed to true before firing error callbacks in order - // to make it re-entrance safe in case destroy() is called within callbacks - - if (this._readableState) { - this._readableState.destroyed = true; - } - - // if this is a duplex stream mark the writable part as destroyed as well - if (this._writableState) { - this._writableState.destroyed = true; - } - - this._destroy(err || null, function (err) { - if (!cb && err) { - pna.nextTick(emitErrorNT, _this, err); - if (_this._writableState) { - _this._writableState.errorEmitted = true; - } - } else if (cb) { - cb(err); - } - }); - - return this; -} - -function undestroy() { - if (this._readableState) { - this._readableState.destroyed = false; - this._readableState.reading = false; - this._readableState.ended = false; - this._readableState.endEmitted = false; - } - - if (this._writableState) { - this._writableState.destroyed = false; - this._writableState.ended = false; - this._writableState.ending = false; - this._writableState.finished = false; - this._writableState.errorEmitted = false; - } -} - -function emitErrorNT(self, err) { - self.emit('error', err); -} - -module.exports = { - destroy: destroy, - undestroy: undestroy -}; -},{"17":17}],27:[function(_dereq_,module,exports){ -module.exports = _dereq_(13).EventEmitter; - -},{"13":13}],28:[function(_dereq_,module,exports){ -arguments[4][11][0].apply(exports,arguments) -},{"11":11}],29:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; - -/**/ - -var Buffer = _dereq_(34).Buffer; -/**/ - -var isEncoding = Buffer.isEncoding || function (encoding) { - encoding = '' + encoding; - switch (encoding && encoding.toLowerCase()) { - case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': - return true; - default: - return false; - } -}; - -function _normalizeEncoding(enc) { - if (!enc) return 'utf8'; - var retried; - while (true) { - switch (enc) { - case 'utf8': - case 'utf-8': - return 'utf8'; - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return 'utf16le'; - case 'latin1': - case 'binary': - return 'latin1'; - case 'base64': - case 'ascii': - case 'hex': - return enc; - default: - if (retried) return; // undefined - enc = ('' + enc).toLowerCase(); - retried = true; - } - } -}; - -// Do not cache `Buffer.isEncoding` when checking encoding names as some -// modules monkey-patch it to support additional encodings -function normalizeEncoding(enc) { - var nenc = _normalizeEncoding(enc); - if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); - return nenc || enc; -} - -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. -exports.StringDecoder = StringDecoder; -function StringDecoder(encoding) { - this.encoding = normalizeEncoding(encoding); - var nb; - switch (this.encoding) { - case 'utf16le': - this.text = utf16Text; - this.end = utf16End; - nb = 4; - break; - case 'utf8': - this.fillLast = utf8FillLast; - nb = 4; - break; - case 'base64': - this.text = base64Text; - this.end = base64End; - nb = 3; - break; - default: - this.write = simpleWrite; - this.end = simpleEnd; - return; - } - this.lastNeed = 0; - this.lastTotal = 0; - this.lastChar = Buffer.allocUnsafe(nb); -} - -StringDecoder.prototype.write = function (buf) { - if (buf.length === 0) return ''; - var r; - var i; - if (this.lastNeed) { - r = this.fillLast(buf); - if (r === undefined) return ''; - i = this.lastNeed; - this.lastNeed = 0; - } else { - i = 0; - } - if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); - return r || ''; -}; - -StringDecoder.prototype.end = utf8End; - -// Returns only complete characters in a Buffer -StringDecoder.prototype.text = utf8Text; - -// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer -StringDecoder.prototype.fillLast = function (buf) { - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); - this.lastNeed -= buf.length; -}; - -// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a -// continuation byte. If an invalid byte is detected, -2 is returned. -function utf8CheckByte(byte) { - if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; - return byte >> 6 === 0x02 ? -1 : -2; -} - -// Checks at most 3 bytes at the end of a Buffer in order to detect an -// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) -// needed to complete the UTF-8 character (if applicable) are returned. -function utf8CheckIncomplete(self, buf, i) { - var j = buf.length - 1; - if (j < i) return 0; - var nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 1; - return nb; - } - if (--j < i || nb === -2) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) self.lastNeed = nb - 2; - return nb; - } - if (--j < i || nb === -2) return 0; - nb = utf8CheckByte(buf[j]); - if (nb >= 0) { - if (nb > 0) { - if (nb === 2) nb = 0;else self.lastNeed = nb - 3; - } - return nb; - } - return 0; -} - -// Validates as many continuation bytes for a multi-byte UTF-8 character as -// needed or are available. If we see a non-continuation byte where we expect -// one, we "replace" the validated continuation bytes we've seen so far with -// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding -// behavior. The continuation byte check is included three times in the case -// where all of the continuation bytes for a character exist in the same buffer. -// It is also done this way as a slight performance increase instead of using a -// loop. -function utf8CheckExtraBytes(self, buf, p) { - if ((buf[0] & 0xC0) !== 0x80) { - self.lastNeed = 0; - return '\ufffd'; - } - if (self.lastNeed > 1 && buf.length > 1) { - if ((buf[1] & 0xC0) !== 0x80) { - self.lastNeed = 1; - return '\ufffd'; - } - if (self.lastNeed > 2 && buf.length > 2) { - if ((buf[2] & 0xC0) !== 0x80) { - self.lastNeed = 2; - return '\ufffd'; - } - } - } -} - -// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. -function utf8FillLast(buf) { - var p = this.lastTotal - this.lastNeed; - var r = utf8CheckExtraBytes(this, buf, p); - if (r !== undefined) return r; - if (this.lastNeed <= buf.length) { - buf.copy(this.lastChar, p, 0, this.lastNeed); - return this.lastChar.toString(this.encoding, 0, this.lastTotal); - } - buf.copy(this.lastChar, p, 0, buf.length); - this.lastNeed -= buf.length; -} - -// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a -// partial character, the character's bytes are buffered until the required -// number of bytes are available. -function utf8Text(buf, i) { - var total = utf8CheckIncomplete(this, buf, i); - if (!this.lastNeed) return buf.toString('utf8', i); - this.lastTotal = total; - var end = buf.length - (total - this.lastNeed); - buf.copy(this.lastChar, 0, end); - return buf.toString('utf8', i, end); -} - -// For UTF-8, a replacement character is added when ending on a partial -// character. -function utf8End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + '\ufffd'; - return r; -} - -// UTF-16LE typically needs two bytes per character, but even if we have an even -// number of bytes available, we need to check if we end on a leading/high -// surrogate. In that case, we need to wait for the next two bytes in order to -// decode the last character properly. -function utf16Text(buf, i) { - if ((buf.length - i) % 2 === 0) { - var r = buf.toString('utf16le', i); - if (r) { - var c = r.charCodeAt(r.length - 1); - if (c >= 0xD800 && c <= 0xDBFF) { - this.lastNeed = 2; - this.lastTotal = 4; - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - return r.slice(0, -1); - } - } - return r; - } - this.lastNeed = 1; - this.lastTotal = 2; - this.lastChar[0] = buf[buf.length - 1]; - return buf.toString('utf16le', i, buf.length - 1); -} - -// For UTF-16LE we do not explicitly append special replacement characters if we -// end on a partial character, we simply let v8 handle that. -function utf16End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) { - var end = this.lastTotal - this.lastNeed; - return r + this.lastChar.toString('utf16le', 0, end); - } - return r; -} - -function base64Text(buf, i) { - var n = (buf.length - i) % 3; - if (n === 0) return buf.toString('base64', i); - this.lastNeed = 3 - n; - this.lastTotal = 3; - if (n === 1) { - this.lastChar[0] = buf[buf.length - 1]; - } else { - this.lastChar[0] = buf[buf.length - 2]; - this.lastChar[1] = buf[buf.length - 1]; - } - return buf.toString('base64', i, buf.length - n); -} - -function base64End(buf) { - var r = buf && buf.length ? this.write(buf) : ''; - if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); - return r; -} - -// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) -function simpleWrite(buf) { - return buf.toString(this.encoding); -} - -function simpleEnd(buf) { - return buf && buf.length ? this.write(buf) : ''; -} -},{"34":34}],30:[function(_dereq_,module,exports){ -module.exports = _dereq_(31).PassThrough - -},{"31":31}],31:[function(_dereq_,module,exports){ -exports = module.exports = _dereq_(22); -exports.Stream = exports; -exports.Readable = exports; -exports.Writable = _dereq_(24); -exports.Duplex = _dereq_(20); -exports.Transform = _dereq_(23); -exports.PassThrough = _dereq_(21); - -},{"20":20,"21":21,"22":22,"23":23,"24":24}],32:[function(_dereq_,module,exports){ -module.exports = _dereq_(31).Transform - -},{"31":31}],33:[function(_dereq_,module,exports){ -module.exports = _dereq_(24); - -},{"24":24}],34:[function(_dereq_,module,exports){ -/* eslint-disable node/no-deprecated-api */ -var buffer = _dereq_(10) -var Buffer = buffer.Buffer - -// alternative to using Object.keys for old browsers -function copyProps (src, dst) { - for (var key in src) { - dst[key] = src[key] - } -} -if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer -} else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer -} - -function SafeBuffer (arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) -} - -// Copy static methods from Buffer -copyProps(Buffer, SafeBuffer) - -SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') - } - return Buffer(arg, encodingOrOffset, length) -} - -SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) - } - } else { - buf.fill(0) - } - return buf -} - -SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return Buffer(size) -} - -SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return buffer.SlowBuffer(size) -} - -},{"10":10}],35:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -module.exports = Stream; - -var EE = _dereq_(13).EventEmitter; -var inherits = _dereq_(15); - -inherits(Stream, EE); -Stream.Readable = _dereq_(31); -Stream.Writable = _dereq_(33); -Stream.Duplex = _dereq_(19); -Stream.Transform = _dereq_(32); -Stream.PassThrough = _dereq_(30); - -// Backwards-compat with node 0.4.x -Stream.Stream = Stream; - - - -// old-style streams. Note that the pipe method (the only relevant -// part of this class) is overridden in the Readable class. - -function Stream() { - EE.call(this); -} - -Stream.prototype.pipe = function(dest, options) { - var source = this; - - function ondata(chunk) { - if (dest.writable) { - if (false === dest.write(chunk) && source.pause) { - source.pause(); - } - } - } - - source.on('data', ondata); - - function ondrain() { - if (source.readable && source.resume) { - source.resume(); - } - } - - dest.on('drain', ondrain); - - // If the 'end' option is not supplied, dest.end() will be called when - // source gets the 'end' or 'close' events. Only dest.end() once. - if (!dest._isStdio && (!options || options.end !== false)) { - source.on('end', onend); - source.on('close', onclose); - } - - var didOnEnd = false; - function onend() { - if (didOnEnd) return; - didOnEnd = true; - - dest.end(); - } - - - function onclose() { - if (didOnEnd) return; - didOnEnd = true; - - if (typeof dest.destroy === 'function') dest.destroy(); - } - - // don't leave dangling pipes when there are errors. - function onerror(er) { - cleanup(); - if (EE.listenerCount(this, 'error') === 0) { - throw er; // Unhandled stream error in pipe. - } - } - - source.on('error', onerror); - dest.on('error', onerror); - - // remove all the event listeners that were added. - function cleanup() { - source.removeListener('data', ondata); - dest.removeListener('drain', ondrain); - - source.removeListener('end', onend); - source.removeListener('close', onclose); - - source.removeListener('error', onerror); - dest.removeListener('error', onerror); - - source.removeListener('end', cleanup); - source.removeListener('close', cleanup); - - dest.removeListener('close', cleanup); - } - - source.on('end', cleanup); - source.on('close', cleanup); - - dest.on('close', cleanup); - - dest.emit('pipe', source); - - // Allow for unix-like usage: A.pipe(B).pipe(C) - return dest; -}; - -},{"13":13,"15":15,"19":19,"30":30,"31":31,"32":32,"33":33}],36:[function(_dereq_,module,exports){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var Buffer = _dereq_(10).Buffer; - -var isBufferEncoding = Buffer.isEncoding - || function(encoding) { - switch (encoding && encoding.toLowerCase()) { - case 'hex': case 'utf8': case 'utf-8': case 'ascii': case 'binary': case 'base64': case 'ucs2': case 'ucs-2': case 'utf16le': case 'utf-16le': case 'raw': return true; - default: return false; - } - } - - -function assertEncoding(encoding) { - if (encoding && !isBufferEncoding(encoding)) { - throw new Error('Unknown encoding: ' + encoding); - } -} - -// StringDecoder provides an interface for efficiently splitting a series of -// buffers into a series of JS strings without breaking apart multi-byte -// characters. CESU-8 is handled as part of the UTF-8 encoding. -// -// @TODO Handling all encodings inside a single object makes it very difficult -// to reason about this code, so it should be split up in the future. -// @TODO There should be a utf8-strict encoding that rejects invalid UTF-8 code -// points as used by CESU-8. -var StringDecoder = exports.StringDecoder = function(encoding) { - this.encoding = (encoding || 'utf8').toLowerCase().replace(/[-_]/, ''); - assertEncoding(encoding); - switch (this.encoding) { - case 'utf8': - // CESU-8 represents each of Surrogate Pair by 3-bytes - this.surrogateSize = 3; - break; - case 'ucs2': - case 'utf16le': - // UTF-16 represents each of Surrogate Pair by 2-bytes - this.surrogateSize = 2; - this.detectIncompleteChar = utf16DetectIncompleteChar; - break; - case 'base64': - // Base-64 stores 3 bytes in 4 chars, and pads the remainder. - this.surrogateSize = 3; - this.detectIncompleteChar = base64DetectIncompleteChar; - break; - default: - this.write = passThroughWrite; - return; - } - - // Enough space to store all bytes of a single character. UTF-8 needs 4 - // bytes, but CESU-8 may require up to 6 (3 bytes per surrogate). - this.charBuffer = new Buffer(6); - // Number of bytes received for the current incomplete multi-byte character. - this.charReceived = 0; - // Number of bytes expected for the current incomplete multi-byte character. - this.charLength = 0; -}; - - -// write decodes the given buffer and returns it as JS string that is -// guaranteed to not contain any partial multi-byte characters. Any partial -// character found at the end of the buffer is buffered up, and will be -// returned when calling write again with the remaining bytes. -// -// Note: Converting a Buffer containing an orphan surrogate to a String -// currently works, but converting a String to a Buffer (via `new Buffer`, or -// Buffer#write) will replace incomplete surrogates with the unicode -// replacement character. See https://codereview.chromium.org/121173009/ . -StringDecoder.prototype.write = function(buffer) { - var charStr = ''; - // if our last write ended with an incomplete multibyte character - while (this.charLength) { - // determine how many remaining bytes this buffer has to offer for this char - var available = (buffer.length >= this.charLength - this.charReceived) ? - this.charLength - this.charReceived : - buffer.length; - - // add the new bytes to the char buffer - buffer.copy(this.charBuffer, this.charReceived, 0, available); - this.charReceived += available; - - if (this.charReceived < this.charLength) { - // still not enough chars in this buffer? wait for more ... - return ''; - } - - // remove bytes belonging to the current character from the buffer - buffer = buffer.slice(available, buffer.length); - - // get the character that was split - charStr = this.charBuffer.slice(0, this.charLength).toString(this.encoding); - - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - var charCode = charStr.charCodeAt(charStr.length - 1); - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - this.charLength += this.surrogateSize; - charStr = ''; - continue; - } - this.charReceived = this.charLength = 0; - - // if there are no more bytes in this buffer, just emit our char - if (buffer.length === 0) { - return charStr; - } - break; - } - - // determine and set charLength / charReceived - this.detectIncompleteChar(buffer); - - var end = buffer.length; - if (this.charLength) { - // buffer the incomplete character bytes we got - buffer.copy(this.charBuffer, 0, buffer.length - this.charReceived, end); - end -= this.charReceived; - } - - charStr += buffer.toString(this.encoding, 0, end); - - var end = charStr.length - 1; - var charCode = charStr.charCodeAt(end); - // CESU-8: lead surrogate (D800-DBFF) is also the incomplete character - if (charCode >= 0xD800 && charCode <= 0xDBFF) { - var size = this.surrogateSize; - this.charLength += size; - this.charReceived += size; - this.charBuffer.copy(this.charBuffer, size, 0, size); - buffer.copy(this.charBuffer, 0, 0, size); - return charStr.substring(0, end); - } - - // or just emit the charStr - return charStr; -}; - -// detectIncompleteChar determines if there is an incomplete UTF-8 character at -// the end of the given buffer. If so, it sets this.charLength to the byte -// length that character, and sets this.charReceived to the number of bytes -// that are available for this character. -StringDecoder.prototype.detectIncompleteChar = function(buffer) { - // determine how many bytes we have to check at the end of this buffer - var i = (buffer.length >= 3) ? 3 : buffer.length; - - // Figure out if one of the last i bytes of our buffer announces an - // incomplete char. - for (; i > 0; i--) { - var c = buffer[buffer.length - i]; - - // See http://en.wikipedia.org/wiki/UTF-8#Description - - // 110XXXXX - if (i == 1 && c >> 5 == 0x06) { - this.charLength = 2; - break; - } - - // 1110XXXX - if (i <= 2 && c >> 4 == 0x0E) { - this.charLength = 3; - break; - } - - // 11110XXX - if (i <= 3 && c >> 3 == 0x1E) { - this.charLength = 4; - break; - } - } - this.charReceived = i; -}; - -StringDecoder.prototype.end = function(buffer) { - var res = ''; - if (buffer && buffer.length) - res = this.write(buffer); - - if (this.charReceived) { - var cr = this.charReceived; - var buf = this.charBuffer; - var enc = this.encoding; - res += buf.slice(0, cr).toString(enc); - } - - return res; -}; - -function passThroughWrite(buffer) { - return buffer.toString(this.encoding); -} - -function utf16DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 2; - this.charLength = this.charReceived ? 2 : 0; -} - -function base64DetectIncompleteChar(buffer) { - this.charReceived = buffer.length % 3; - this.charLength = this.charReceived ? 3 : 0; -} - -},{"10":10}],37:[function(_dereq_,module,exports){ -(function (global){ - -/** - * Module exports. - */ - -module.exports = deprecate; - -/** - * Mark that a method should not be used. - * Returns a modified function which warns once by default. - * - * If `localStorage.noDeprecation = true` is set, then it is a no-op. - * - * If `localStorage.throwDeprecation = true` is set, then deprecated functions - * will throw an Error when invoked. - * - * If `localStorage.traceDeprecation = true` is set, then deprecated functions - * will invoke `console.trace()` instead of `console.error()`. - * - * @param {Function} fn - the function to deprecate - * @param {String} msg - the string to print to the console when `fn` is invoked - * @returns {Function} a new "deprecated" version of `fn` - * @api public - */ - -function deprecate (fn, msg) { - if (config('noDeprecation')) { - return fn; - } - - var warned = false; - function deprecated() { - if (!warned) { - if (config('throwDeprecation')) { - throw new Error(msg); - } else if (config('traceDeprecation')) { - console.trace(msg); - } else { - console.warn(msg); - } - warned = true; - } - return fn.apply(this, arguments); - } - - return deprecated; -} - -/** - * Checks `localStorage` for boolean values for the given `name`. - * - * @param {String} name - * @returns {Boolean} - * @api private - */ - -function config (name) { - // accessing global.localStorage can trigger a DOMException in sandboxed iframes - try { - if (!global.localStorage) return false; - } catch (_) { - return false; - } - var val = global.localStorage[name]; - if (null == val) return false; - return String(val).toLowerCase() === 'true'; -} - -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) - -},{}],38:[function(_dereq_,module,exports){ +},{}],13:[function(_dereq_,module,exports){ /* * Copyright (c) 2016, Pierre-Anthony Lemieux * All rights reserved. @@ -8976,7 +5982,7 @@ function config (name) { for (c = 1; c < estack[0].contents.length; c++) { if (estack[0].contents[c] instanceof AnonymousSpan && - cs[cs.length - 1] instanceof AnonymousSpan) { + cs[cs.length - 1] instanceof AnonymousSpan) { cs[cs.length - 1].text += estack[0].contents[c].text; @@ -8995,9 +6001,8 @@ function config (name) { // remove redundant nested anonymous spans (9.3.3(1)(c)) if (estack[0] instanceof Span && - estack[0].contents.length === 1 && - estack[0].contents[0] instanceof AnonymousSpan && - estack[0].text === null) { + estack[0].contents.length === 1 && + estack[0].contents[0] instanceof AnonymousSpan) { estack[0].text = estack[0].contents[0].text; delete estack[0].contents; @@ -9007,15 +6012,15 @@ function config (name) { } else if (estack[0] instanceof ForeignElement) { if (estack[0].node.uri === imscNames.ns_tt && - estack[0].node.local === 'metadata') { + estack[0].node.local === 'metadata') { /* leave the metadata element */ metadata_depth--; } else if (metadata_depth > 0 && - metadataHandler && - 'onCloseTag' in metadataHandler) { + metadataHandler && + 'onCloseTag' in metadataHandler) { /* end of child of metadata element */ @@ -9049,17 +6054,17 @@ function config (name) { } else if (estack[0] instanceof Span || estack[0] instanceof P) { /* create an anonymous span */ - + var s = new AnonymousSpan(); - + s.initFromText(doc, estack[0], str, xmlspacestack[0], errorHandler); estack[0].contents.push(s); } else if (estack[0] instanceof ForeignElement && - metadata_depth > 0 && - metadataHandler && - 'onText' in metadataHandler) { + metadata_depth > 0 && + metadataHandler && + 'onText' in metadataHandler) { /* text node within a child of metadata element */ @@ -9126,7 +6131,7 @@ function config (name) { if (doc !== null) { - reportFatal("Two elements at (" + this.line + "," + this.column + ")"); + reportFatal(errorHandler, "Two elements at (" + this.line + "," + this.column + ")"); } @@ -9139,7 +6144,7 @@ function config (name) { } else if (node.local === 'head') { if (!(estack[0] instanceof TT)) { - reportFatal("Parent of element is not at (" + this.line + "," + this.column + ")"); + reportFatal(errorHandler, "Parent of element is not at (" + this.line + "," + this.column + ")"); } if (doc.head !== null) { @@ -9153,7 +6158,7 @@ function config (name) { } else if (node.local === 'styling') { if (!(estack[0] instanceof Head)) { - reportFatal("Parent of element is not at (" + this.line + "," + this.column + ")"); + reportFatal(errorHandler, "Parent of element is not at (" + this.line + "," + this.column + ")"); } if (doc.head.styling !== null) { @@ -9178,7 +6183,7 @@ function config (name) { if (!s.id) { - reportError("