/*!
 LZ-UTF8 v0.5.5

 Copyright (c) 2018, Rotem Dan
 Released under the MIT license.

 Build date: 2018-07-30 

 Please report any issue at https://github.com/rotemdan/lzutf8.js/issues
*/
var LZUTF8;
(function (LZUTF8) {
    LZUTF8.runningInNodeJS = function () {
        return ((typeof process === "object") && (typeof process.versions === "object") && (typeof process.versions.node === "string"));
    };
    LZUTF8.runningInMainNodeJSModule = function () {
        return LZUTF8.runningInNodeJS() && require.main === module;
    };
    LZUTF8.commonJSAvailable = function () {
        return typeof module === "object" && typeof module.exports === "object";
    };
    LZUTF8.runningInWebWorker = function () {
        return typeof window === "undefined" && typeof self === "object" && typeof self.addEventListener === "function" && typeof self.close === "function";
    };
    LZUTF8.runningInNodeChildProcess = function () {
        return LZUTF8.runningInNodeJS() && typeof process.send === "function";
    };
    LZUTF8.runningInNullOrigin = function () {
        if (typeof window !== "object" || typeof window.location !== "object")
            return false;
        return document.location.protocol !== 'http:' && document.location.protocol !== 'https:';
    };
    LZUTF8.webWorkersAvailable = function () {
        if (typeof Worker !== "function" || LZUTF8.runningInNullOrigin())
            return false;
        if (LZUTF8.runningInNodeJS())
            return false;
        if (navigator && navigator.userAgent && navigator.userAgent.indexOf("Android 4.3") >= 0)
            return false;
        return true;
    };
    LZUTF8.log = function (message, appendToDocument) {
        if (appendToDocument === void 0) { appendToDocument = false; }
        if (typeof console !== "object")
            return;
        console.log(message);
        if (appendToDocument && typeof document == "object")
            document.body.innerHTML += message + "<br/>";
    };
    LZUTF8.createErrorMessage = function (exception, title) {
        if (title === void 0) { title = "Unhandled exception"; }
        if (exception == null)
            return title;
        title += ": ";
        if (typeof exception.content === "object") {
            if (LZUTF8.runningInNodeJS()) {
                return title + exception.content.stack;
            }
            else {
                var exceptionJSON = JSON.stringify(exception.content);
                if (exceptionJSON !== "{}")
                    return title + exceptionJSON;
                else
                    return title + exception.content;
            }
        }
        else if (typeof exception.content === "string") {
            return title + exception.content;
        }
        else {
            return title + exception;
        }
    };
    LZUTF8.printExceptionAndStackTraceToConsole = function (exception, title) {
        if (title === void 0) { title = "Unhandled exception"; }
        LZUTF8.log(LZUTF8.createErrorMessage(exception, title));
    };
    LZUTF8.getGlobalObject = function () {
        if (typeof global === "object")
            return global;
        else if (typeof window === "object")
            return window;
        else if (typeof self === "object")
            return self;
        else
            return {};
    };
    LZUTF8.toString = Object.prototype.toString;
    if (LZUTF8.commonJSAvailable())
        module.exports = LZUTF8;
})(LZUTF8 || (LZUTF8 = {}));
if (typeof Uint8Array === "function" && new Uint8Array(1).subarray(1).byteLength !== 0) {
    var subarray = function (start, end) {
        var clamp = function (v, min, max) { return v < min ? min : v > max ? max : v; };
        start = start | 0;
        end = end | 0;
        if (arguments.length < 1)
            start = 0;
        if (arguments.length < 2)
            end = this.length;
        if (start < 0)
            start = this.length + start;
        if (end < 0)
            end = this.length + end;
        start = clamp(start, 0, this.length);
        end = clamp(end, 0, this.length);
        var len = end - start;
        if (len < 0)
            len = 0;
        return new this.constructor(this.buffer, this.byteOffset + start * this.BYTES_PER_ELEMENT, len);
    };
    var types = ['Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array'];
    var globalObject = void 0;
    if (typeof window === "object")
        globalObject = window;
    else if (typeof self === "object")
        globalObject = self;
    if (globalObject !== undefined) {
        for (var i = 0; i < types.length; i++) {
            if (globalObject[types[i]])
                globalObject[types[i]].prototype.subarray = subarray;
        }
    }
}
var LZUTF8;
(function (LZUTF8) {
    var AsyncCompressor = (function () {
        function AsyncCompressor() {
        }
        AsyncCompressor.compressAsync = function (input, options, callback) {
            var timer = new LZUTF8.Timer();
            var compressor = new LZUTF8.Compressor();
            if (!callback)
                throw new TypeError("compressAsync: No callback argument given");
            if (typeof input === "string") {
                input = LZUTF8.encodeUTF8(input);
            }
            else if (input == null || !(input instanceof Uint8Array)) {
                callback(undefined, new TypeError("compressAsync: Invalid input argument, only 'string' and 'Uint8Array' are supported"));
                return;
            }
            var sourceBlocks = LZUTF8.ArrayTools.splitByteArray(input, options.blockSize);
            var compressedBlocks = [];
            var compressBlocksStartingAt = function (index) {
                if (index < sourceBlocks.length) {
                    var compressedBlock = void 0;
                    try {
                        compressedBlock = compressor.compressBlock(sourceBlocks[index]);
                    }
                    catch (e) {
                        callback(undefined, e);
                        return;
                    }
                    compressedBlocks.push(compressedBlock);
                    if (timer.getElapsedTime() <= 20) {
                        compressBlocksStartingAt(index + 1);
                    }
                    else {
                        LZUTF8.enqueueImmediate(function () { return compressBlocksStartingAt(index + 1); });
                        timer.restart();
                    }
                }
                else {
                    var joinedCompressedBlocks_1 = LZUTF8.ArrayTools.concatUint8Arrays(compressedBlocks);
                    LZUTF8.enqueueImmediate(function () {
                        var result;
                        try {
                            result = LZUTF8.CompressionCommon.encodeCompressedBytes(joinedCompressedBlocks_1, options.outputEncoding);
                        }
                        catch (e) {
                            callback(undefined, e);
                            return;
                        }
                        LZUTF8.enqueueImmediate(function () { return callback(result); });
                    });
                }
            };
            LZUTF8.enqueueImmediate(function () { return compressBlocksStartingAt(0); });
        };
        AsyncCompressor.createCompressionStream = function () {
            var compressor = new LZUTF8.Compressor();
            var NodeStream = require("stream");
            var compressionStream = new NodeStream.Transform({ decodeStrings: true, highWaterMark: 65536 });
            compressionStream._transform = function (data, encoding, done) {
                var buffer;
                try {
                    buffer = LZUTF8.BufferTools.uint8ArrayToBuffer(compressor.compressBlock(LZUTF8.BufferTools.bufferToUint8Array(data)));
                }
                catch (e) {
                    compressionStream.emit("error", e);
                    return;
                }
                compressionStream.push(buffer);
                done();
            };
            return compressionStream;
        };
        return AsyncCompressor;
    }());
    LZUTF8.AsyncCompressor = AsyncCompressor;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var AsyncDecompressor = (function () {
        function AsyncDecompressor() {
        }
        AsyncDecompressor.decompressAsync = function (input, options, callback) {
            if (!callback)
                throw new TypeError("decompressAsync: No callback argument given");
            var timer = new LZUTF8.Timer();
            try {
                input = LZUTF8.CompressionCommon.decodeCompressedBytes(input, options.inputEncoding);
            }
            catch (e) {
                callback(undefined, e);
                return;
            }
            var decompressor = new LZUTF8.Decompressor();
            var sourceBlocks = LZUTF8.ArrayTools.splitByteArray(input, options.blockSize);
            var decompressedBlocks = [];
            var decompressBlocksStartingAt = function (index) {
                if (index < sourceBlocks.length) {
                    var decompressedBlock = void 0;
                    try {
                        decompressedBlock = decompressor.decompressBlock(sourceBlocks[index]);
                    }
                    catch (e) {
                        callback(undefined, e);
                        return;
                    }
                    decompressedBlocks.push(decompressedBlock);
                    if (timer.getElapsedTime() <= 20) {
                        decompressBlocksStartingAt(index + 1);
                    }
                    else {
                        LZUTF8.enqueueImmediate(function () { return decompressBlocksStartingAt(index + 1); });
                        timer.restart();
                    }
                }
                else {
                    var joinedDecompressedBlocks_1 = LZUTF8.ArrayTools.concatUint8Arrays(decompressedBlocks);
                    LZUTF8.enqueueImmediate(function () {
                        var result;
                        try {
                            result = LZUTF8.CompressionCommon.encodeDecompressedBytes(joinedDecompressedBlocks_1, options.outputEncoding);
                        }
                        catch (e) {
                            callback(undefined, e);
                            return;
                        }
                        LZUTF8.enqueueImmediate(function () { return callback(result); });
                    });
                }
            };
            LZUTF8.enqueueImmediate(function () { return decompressBlocksStartingAt(0); });
        };
        AsyncDecompressor.createDecompressionStream = function () {
            var decompressor = new LZUTF8.Decompressor();
            var NodeStream = require("stream");
            var decompressionStream = new NodeStream.Transform({ decodeStrings: true, highWaterMark: 65536 });
            decompressionStream._transform = function (data, encoding, done) {
                var buffer;
                try {
                    buffer = LZUTF8.BufferTools.uint8ArrayToBuffer(decompressor.decompressBlock(LZUTF8.BufferTools.bufferToUint8Array(data)));
                }
                catch (e) {
                    decompressionStream.emit("error", e);
                    return;
                }
                decompressionStream.push(buffer);
                done();
            };
            return decompressionStream;
        };
        return AsyncDecompressor;
    }());
    LZUTF8.AsyncDecompressor = AsyncDecompressor;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var WebWorker;
    (function (WebWorker) {
        WebWorker.compressAsync = function (input, options, callback) {
            if (options.inputEncoding == "ByteArray") {
                if (!(input instanceof Uint8Array)) {
                    callback(undefined, new TypeError("compressAsync: input is not a Uint8Array"));
                    return;
                }
            }
            var request = {
                token: Math.random().toString(),
                type: "compress",
                data: input,
                inputEncoding: options.inputEncoding,
                outputEncoding: options.outputEncoding
            };
            var responseListener = function (e) {
                var response = e.data;
                if (!response || response.token != request.token)
                    return;
                WebWorker.globalWorker.removeEventListener("message", responseListener);
                if (response.type == "error")
                    callback(undefined, new Error(response.error));
                else
                    callback(response.data);
            };
            WebWorker.globalWorker.addEventListener("message", responseListener);
            WebWorker.globalWorker.postMessage(request, []);
        };
        WebWorker.decompressAsync = function (input, options, callback) {
            var request = {
                token: Math.random().toString(),
                type: "decompress",
                data: input,
                inputEncoding: options.inputEncoding,
                outputEncoding: options.outputEncoding
            };
            var responseListener = function (e) {
                var response = e.data;
                if (!response || response.token != request.token)
                    return;
                WebWorker.globalWorker.removeEventListener("message", responseListener);
                if (response.type == "error")
                    callback(undefined, new Error(response.error));
                else
                    callback(response.data);
            };
            WebWorker.globalWorker.addEventListener("message", responseListener);
            WebWorker.globalWorker.postMessage(request, []);
        };
        WebWorker.installWebWorkerIfNeeded = function () {
            if (typeof self == "object" && self.document === undefined && self.addEventListener != undefined) {
                self.addEventListener("message", function (e) {
                    var request = e.data;
                    if (request.type == "compress") {
                        var compressedData = void 0;
                        try {
                            compressedData = LZUTF8.compress(request.data, { outputEncoding: request.outputEncoding });
                        }
                        catch (e) {
                            self.postMessage({ token: request.token, type: "error", error: LZUTF8.createErrorMessage(e) }, []);
                            return;
                        }
                        var response = {
                            token: request.token,
                            type: "compressionResult",
                            data: compressedData,
                            encoding: request.outputEncoding,
                        };
                        if (response.data instanceof Uint8Array && navigator.appVersion.indexOf("MSIE 10") === -1)
                            self.postMessage(response, [response.data.buffer]);
                        else
                            self.postMessage(response, []);
                    }
                    else if (request.type == "decompress") {
                        var decompressedData = void 0;
                        try {
                            decompressedData = LZUTF8.decompress(request.data, { inputEncoding: request.inputEncoding, outputEncoding: request.outputEncoding });
                        }
                        catch (e) {
                            self.postMessage({ token: request.token, type: "error", error: LZUTF8.createErrorMessage(e) }, []);
                            return;
                        }
                        var response = {
                            token: request.token,
                            type: "decompressionResult",
                            data: decompressedData,
                            encoding: request.outputEncoding,
                        };
                        if (response.data instanceof Uint8Array && navigator.appVersion.indexOf("MSIE 10") === -1)
                            self.postMessage(response, [response.data.buffer]);
                        else
                            self.postMessage(response, []);
                    }
                });
                self.addEventListener("error", function (e) {
                    LZUTF8.log(LZUTF8.createErrorMessage(e.error, "Unexpected LZUTF8 WebWorker exception"));
                });
            }
        };
        WebWorker.createGlobalWorkerIfNeeded = function () {
            if (WebWorker.globalWorker)
                return true;
            if (!LZUTF8.webWorkersAvailable())
                return false;
            if (!WebWorker.scriptURI && typeof document === "object") {
                var scriptElement = document.getElementById("lzutf8");
                if (scriptElement != null)
                    WebWorker.scriptURI = scriptElement.getAttribute("src") || undefined;
            }
            if (WebWorker.scriptURI) {
                WebWorker.globalWorker = new Worker(WebWorker.scriptURI);
                return true;
            }
            else {
                return false;
            }
        };
        WebWorker.terminate = function () {
            if (WebWorker.globalWorker) {
                WebWorker.globalWorker.terminate();
                WebWorker.globalWorker = undefined;
            }
        };
    })(WebWorker = LZUTF8.WebWorker || (LZUTF8.WebWorker = {}));
    WebWorker.installWebWorkerIfNeeded();
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var ArraySegment = (function () {
        function ArraySegment(container, startPosition, length) {
            this.container = container;
            this.startPosition = startPosition;
            this.length = length;
        }
        ArraySegment.prototype.get = function (index) {
            return this.container[this.startPosition + index];
        };
        ArraySegment.prototype.getInReversedOrder = function (reverseIndex) {
            return this.container[this.startPosition + this.length - 1 - reverseIndex];
        };
        ArraySegment.prototype.set = function (index, value) {
            this.container[this.startPosition + index] = value;
        };
        return ArraySegment;
    }());
    LZUTF8.ArraySegment = ArraySegment;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var ArrayTools;
    (function (ArrayTools) {
        ArrayTools.copyElements = function (source, sourceIndex, destination, destinationIndex, count) {
            while (count--)
                destination[destinationIndex++] = source[sourceIndex++];
        };
        ArrayTools.zeroElements = function (collection, index, count) {
            while (count--)
                collection[index++] = 0;
        };
        ArrayTools.countNonzeroValuesInArray = function (array) {
            var result = 0;
            for (var i = 0; i < array.length; i++)
                if (array[i])
                    result++;
            return result;
        };
        ArrayTools.truncateStartingElements = function (array, truncatedLength) {
            if (array.length <= truncatedLength)
                throw new RangeError("truncateStartingElements: Requested length should be smaller than array length");
            var sourcePosition = array.length - truncatedLength;
            for (var i = 0; i < truncatedLength; i++)
                array[i] = array[sourcePosition + i];
            array.length = truncatedLength;
        };
        ArrayTools.doubleByteArrayCapacity = function (array) {
            var newArray = new Uint8Array(array.length * 2);
            newArray.set(array);
            return newArray;
        };
        ArrayTools.concatUint8Arrays = function (arrays) {
            var totalLength = 0;
            for (var _i = 0, arrays_1 = arrays; _i < arrays_1.length; _i++) {
                var array = arrays_1[_i];
                totalLength += array.length;
            }
            var result = new Uint8Array(totalLength);
            var offset = 0;
            for (var _a = 0, arrays_2 = arrays; _a < arrays_2.length; _a++) {
                var array = arrays_2[_a];
                result.set(array, offset);
                offset += array.length;
            }
            return result;
        };
        ArrayTools.splitByteArray = function (byteArray, maxPartLength) {
            var result = [];
            for (var offset = 0; offset < byteArray.length;) {
                var blockLength = Math.min(maxPartLength, byteArray.length - offset);
                result.push(byteArray.subarray(offset, offset + blockLength));
                offset += blockLength;
            }
            return result;
        };
    })(ArrayTools = LZUTF8.ArrayTools || (LZUTF8.ArrayTools = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var BufferTools;
    (function (BufferTools) {
        BufferTools.convertToUint8ArrayIfNeeded = function (input) {
            if (typeof Buffer === "function" && Buffer.isBuffer(input))
                return BufferTools.bufferToUint8Array(input);
            else
                return input;
        };
        BufferTools.uint8ArrayToBuffer = function (arr) {
            if (Buffer.prototype instanceof Uint8Array) {
                var arrClone = new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
                Object["setPrototypeOf"](arrClone, Buffer.prototype);
                return arrClone;
            }
            else {
                var len = arr.length;
                var buf = new Buffer(len);
                for (var i = 0; i < len; i++)
                    buf[i] = arr[i];
                return buf;
            }
        };
        BufferTools.bufferToUint8Array = function (buf) {
            if (Buffer.prototype instanceof Uint8Array) {
                return new Uint8Array(buf["buffer"], buf["byteOffset"], buf["byteLength"]);
            }
            else {
                var len = buf.length;
                var arr = new Uint8Array(len);
                for (var i = 0; i < len; i++)
                    arr[i] = buf[i];
                return arr;
            }
        };
    })(BufferTools = LZUTF8.BufferTools || (LZUTF8.BufferTools = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var CompressionCommon;
    (function (CompressionCommon) {
        CompressionCommon.getCroppedBuffer = function (buffer, cropStartOffset, cropLength, additionalCapacity) {
            if (additionalCapacity === void 0) { additionalCapacity = 0; }
            var croppedBuffer = new Uint8Array(cropLength + additionalCapacity);
            croppedBuffer.set(buffer.subarray(cropStartOffset, cropStartOffset + cropLength));
            return croppedBuffer;
        };
        CompressionCommon.getCroppedAndAppendedByteArray = function (bytes, cropStartOffset, cropLength, byteArrayToAppend) {
            return LZUTF8.ArrayTools.concatUint8Arrays([bytes.subarray(cropStartOffset, cropStartOffset + cropLength), byteArrayToAppend]);
        };
        CompressionCommon.detectCompressionSourceEncoding = function (input) {
            if (input == null)
                throw new TypeError("detectCompressionSourceEncoding: input is null or undefined");
            if (typeof input === "string")
                return "String";
            else if (input instanceof Uint8Array || (typeof Buffer === "function" && Buffer.isBuffer(input)))
                return "ByteArray";
            else
                throw new TypeError("detectCompressionSourceEncoding: input must be of type 'string', 'Uint8Array' or 'Buffer'");
        };
        CompressionCommon.encodeCompressedBytes = function (compressedBytes, outputEncoding) {
            switch (outputEncoding) {
                case "ByteArray":
                    return compressedBytes;
                case "Buffer":
                    return LZUTF8.BufferTools.uint8ArrayToBuffer(compressedBytes);
                case "Base64":
                    return LZUTF8.encodeBase64(compressedBytes);
                case "BinaryString":
                    return LZUTF8.encodeBinaryString(compressedBytes);
                case "StorageBinaryString":
                    return LZUTF8.encodeStorageBinaryString(compressedBytes);
                default:
                    throw new TypeError("encodeCompressedBytes: invalid output encoding requested");
            }
        };
        CompressionCommon.decodeCompressedBytes = function (compressedData, inputEncoding) {
            if (inputEncoding == null)
                throw new TypeError("decodeCompressedData: Input is null or undefined");
            switch (inputEncoding) {
                case "ByteArray":
                case "Buffer":
                    var normalizedBytes = LZUTF8.BufferTools.convertToUint8ArrayIfNeeded(compressedData);
                    if (!(normalizedBytes instanceof Uint8Array))
                        throw new TypeError("decodeCompressedData: 'ByteArray' or 'Buffer' input type was specified but input is not a Uint8Array or Buffer");
                    return normalizedBytes;
                case "Base64":
                    if (typeof compressedData !== "string")
                        throw new TypeError("decodeCompressedData: 'Base64' input type was specified but input is not a string");
                    return LZUTF8.decodeBase64(compressedData);
                case "BinaryString":
                    if (typeof compressedData !== "string")
                        throw new TypeError("decodeCompressedData: 'BinaryString' input type was specified but input is not a string");
                    return LZUTF8.decodeBinaryString(compressedData);
                case "StorageBinaryString":
                    if (typeof compressedData !== "string")
                        throw new TypeError("decodeCompressedData: 'StorageBinaryString' input type was specified but input is not a string");
                    return LZUTF8.decodeStorageBinaryString(compressedData);
                default:
                    throw new TypeError("decodeCompressedData: invalid input encoding requested: '" + inputEncoding + "'");
            }
        };
        CompressionCommon.encodeDecompressedBytes = function (decompressedBytes, outputEncoding) {
            switch (outputEncoding) {
                case "String":
                    return LZUTF8.decodeUTF8(decompressedBytes);
                case "ByteArray":
                    return decompressedBytes;
                case "Buffer":
                    if (typeof Buffer !== "function")
                        throw new TypeError("encodeDecompressedBytes: a 'Buffer' type was specified but is not supported at the current envirnment");
                    return LZUTF8.BufferTools.uint8ArrayToBuffer(decompressedBytes);
                default:
                    throw new TypeError("encodeDecompressedBytes: invalid output encoding requested");
            }
        };
    })(CompressionCommon = LZUTF8.CompressionCommon || (LZUTF8.CompressionCommon = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var EventLoop;
    (function (EventLoop) {
        var queuedFunctions = [];
        var asyncFlushFunc;
        EventLoop.enqueueImmediate = function (func) {
            queuedFunctions.push(func);
            if (queuedFunctions.length === 1)
                asyncFlushFunc();
        };
        EventLoop.initializeScheduler = function () {
            var flush = function () {
                for (var _i = 0, queuedFunctions_1 = queuedFunctions; _i < queuedFunctions_1.length; _i++) {
                    var func = queuedFunctions_1[_i];
                    try {
                        func.call(undefined);
                    }
                    catch (exception) {
                        LZUTF8.printExceptionAndStackTraceToConsole(exception, "enqueueImmediate exception");
                    }
                }
                queuedFunctions.length = 0;
            };
            if (LZUTF8.runningInNodeJS()) {
                asyncFlushFunc = function () { return setImmediate(function () { return flush(); }); };
            }
            if (typeof window === "object" && typeof window.addEventListener === "function" && typeof window.postMessage === "function") {
                var token_1 = "enqueueImmediate-" + Math.random().toString();
                window.addEventListener("message", function (event) {
                    if (event.data === token_1)
                        flush();
                });
                var targetOrigin_1;
                if (LZUTF8.runningInNullOrigin())
                    targetOrigin_1 = '*';
                else
                    targetOrigin_1 = window.location.href;
                asyncFlushFunc = function () { return window.postMessage(token_1, targetOrigin_1); };
            }
            else if (typeof MessageChannel === "function" && typeof MessagePort === "function") {
                var channel_1 = new MessageChannel();
                channel_1.port1.onmessage = function () { return flush(); };
                asyncFlushFunc = function () { return channel_1.port2.postMessage(0); };
            }
            else {
                asyncFlushFunc = function () { return setTimeout(function () { return flush(); }, 0); };
            }
        };
        EventLoop.initializeScheduler();
    })(EventLoop = LZUTF8.EventLoop || (LZUTF8.EventLoop = {}));
    LZUTF8.enqueueImmediate = function (func) { return EventLoop.enqueueImmediate(func); };
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var ObjectTools;
    (function (ObjectTools) {
        ObjectTools.override = function (obj, newPropertyValues) {
            return ObjectTools.extend(obj, newPropertyValues);
        };
        ObjectTools.extend = function (obj, newProperties) {
            if (obj == null)
                throw new TypeError("obj is null or undefined");
            if (typeof obj !== "object")
                throw new TypeError("obj is not an object");
            if (newProperties == null)
                newProperties = {};
            if (typeof newProperties !== "object")
                throw new TypeError("newProperties is not an object");
            if (newProperties != null) {
                for (var property in newProperties)
                    obj[property] = newProperties[property];
            }
            return obj;
        };
    })(ObjectTools = LZUTF8.ObjectTools || (LZUTF8.ObjectTools = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    LZUTF8.getRandomIntegerInRange = function (low, high) {
        return low + Math.floor(Math.random() * (high - low));
    };
    LZUTF8.getRandomUTF16StringOfLength = function (length) {
        var randomString = "";
        for (var i = 0; i < length; i++) {
            var randomCodePoint = void 0;
            do {
                randomCodePoint = LZUTF8.getRandomIntegerInRange(0, 0x10FFFF + 1);
            } while (randomCodePoint >= 0xD800 && randomCodePoint <= 0xDFFF);
            randomString += LZUTF8.Encoding.CodePoint.decodeToString(randomCodePoint);
        }
        return randomString;
    };
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var StringBuilder = (function () {
        function StringBuilder(outputBufferCapacity) {
            if (outputBufferCapacity === void 0) { outputBufferCapacity = 1024; }
            this.outputBufferCapacity = outputBufferCapacity;
            this.outputPosition = 0;
            this.outputString = "";
            this.outputBuffer = new Uint16Array(this.outputBufferCapacity);
        }
        StringBuilder.prototype.appendCharCode = function (charCode) {
            this.outputBuffer[this.outputPosition++] = charCode;
            if (this.outputPosition === this.outputBufferCapacity)
                this.flushBufferToOutputString();
        };
        StringBuilder.prototype.appendCharCodes = function (charCodes) {
            for (var i = 0, length_1 = charCodes.length; i < length_1; i++)
                this.appendCharCode(charCodes[i]);
        };
        StringBuilder.prototype.appendString = function (str) {
            for (var i = 0, length_2 = str.length; i < length_2; i++)
                this.appendCharCode(str.charCodeAt(i));
        };
        StringBuilder.prototype.appendCodePoint = function (codePoint) {
            if (codePoint <= 0xFFFF) {
                this.appendCharCode(codePoint);
            }
            else if (codePoint <= 0x10FFFF) {
                this.appendCharCode(0xD800 + ((codePoint - 0x10000) >>> 10));
                this.appendCharCode(0xDC00 + ((codePoint - 0x10000) & 1023));
            }
            else
                throw new Error("appendCodePoint: A code point of " + codePoint + " cannot be encoded in UTF-16");
        };
        StringBuilder.prototype.getOutputString = function () {
            this.flushBufferToOutputString();
            return this.outputString;
        };
        StringBuilder.prototype.flushBufferToOutputString = function () {
            if (this.outputPosition === this.outputBufferCapacity)
                this.outputString += String.fromCharCode.apply(null, this.outputBuffer);
            else
                this.outputString += String.fromCharCode.apply(null, this.outputBuffer.subarray(0, this.outputPosition));
            this.outputPosition = 0;
        };
        return StringBuilder;
    }());
    LZUTF8.StringBuilder = StringBuilder;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Timer = (function () {
        function Timer() {
            this.restart();
        }
        Timer.prototype.restart = function () {
            this.startTime = Timer.getTimestamp();
        };
        Timer.prototype.getElapsedTime = function () {
            return Timer.getTimestamp() - this.startTime;
        };
        Timer.prototype.getElapsedTimeAndRestart = function () {
            var elapsedTime = this.getElapsedTime();
            this.restart();
            return elapsedTime;
        };
        Timer.prototype.logAndRestart = function (title, logToDocument) {
            if (logToDocument === void 0) { logToDocument = true; }
            var elapsedTime = this.getElapsedTime();
            var message = title + ": " + elapsedTime.toFixed(3) + "ms";
            LZUTF8.log(message, logToDocument);
            this.restart();
            return elapsedTime;
        };
        Timer.getTimestamp = function () {
            if (!this.timestampFunc)
                this.createGlobalTimestampFunction();
            return this.timestampFunc();
        };
        Timer.getMicrosecondTimestamp = function () {
            return Math.floor(Timer.getTimestamp() * 1000);
        };
        Timer.createGlobalTimestampFunction = function () {
            if (typeof process === "object" && typeof process.hrtime === "function") {
                var baseTimestamp_1 = 0;
                this.timestampFunc = function () {
                    var nodeTimeStamp = process.hrtime();
                    var millisecondTime = (nodeTimeStamp[0] * 1000) + (nodeTimeStamp[1] / 1000000);
                    return baseTimestamp_1 + millisecondTime;
                };
                baseTimestamp_1 = Date.now() - this.timestampFunc();
            }
            else if (typeof chrome === "object" && chrome.Interval) {
                var baseTimestamp_2 = Date.now();
                var chromeIntervalObject_1 = new chrome.Interval();
                chromeIntervalObject_1.start();
                this.timestampFunc = function () { return baseTimestamp_2 + chromeIntervalObject_1.microseconds() / 1000; };
            }
            else if (typeof performance === "object" && performance.now) {
                var baseTimestamp_3 = Date.now() - performance.now();
                this.timestampFunc = function () { return baseTimestamp_3 + performance.now(); };
            }
            else if (Date.now) {
                this.timestampFunc = function () { return Date.now(); };
            }
            else {
                this.timestampFunc = function () { return (new Date()).getTime(); };
            }
        };
        return Timer;
    }());
    LZUTF8.Timer = Timer;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Compressor = (function () {
        function Compressor(useCustomHashTable) {
            if (useCustomHashTable === void 0) { useCustomHashTable = true; }
            this.MinimumSequenceLength = 4;
            this.MaximumSequenceLength = 31;
            this.MaximumMatchDistance = 32767;
            this.PrefixHashTableSize = 65537;
            this.inputBufferStreamOffset = 1;
            if (useCustomHashTable && typeof Uint32Array == "function")
                this.prefixHashTable = new LZUTF8.CompressorCustomHashTable(this.PrefixHashTableSize);
            else
                this.prefixHashTable = new LZUTF8.CompressorSimpleHashTable(this.PrefixHashTableSize);
        }
        Compressor.prototype.compressBlock = function (input) {
            if (input === undefined || input === null)
                throw new TypeError("compressBlock: undefined or null input received");
            if (typeof input == "string")
                input = LZUTF8.encodeUTF8(input);
            input = LZUTF8.BufferTools.convertToUint8ArrayIfNeeded(input);
            return this.compressUtf8Block(input);
        };
        Compressor.prototype.compressUtf8Block = function (utf8Bytes) {
            if (!utf8Bytes || utf8Bytes.length == 0)
                return new Uint8Array(0);
            var bufferStartingReadOffset = this.cropAndAddNewBytesToInputBuffer(utf8Bytes);
            var inputBuffer = this.inputBuffer;
            var inputBufferLength = this.inputBuffer.length;
            this.outputBuffer = new Uint8Array(utf8Bytes.length);
            this.outputBufferPosition = 0;
            var latestMatchEndPosition = 0;
            for (var readPosition = bufferStartingReadOffset; readPosition < inputBufferLength; readPosition++) {
                var inputValue = inputBuffer[readPosition];
                var withinAMatchedRange = readPosition < latestMatchEndPosition;
                if (readPosition > inputBufferLength - this.MinimumSequenceLength) {
                    if (!withinAMatchedRange)
                        this.outputRawByte(inputValue);
                    continue;
                }
                var targetBucketIndex = this.getBucketIndexForPrefix(readPosition);
                if (!withinAMatchedRange) {
                    var matchLocator = this.findLongestMatch(readPosition, targetBucketIndex);
                    if (matchLocator != null) {
                        this.outputPointerBytes(matchLocator.length, matchLocator.distance);
                        latestMatchEndPosition = readPosition + matchLocator.length;
                        withinAMatchedRange = true;
                    }
                }
                if (!withinAMatchedRange)
                    this.outputRawByte(inputValue);
                var inputStreamPosition = this.inputBufferStreamOffset + readPosition;
                this.prefixHashTable.addValueToBucket(targetBucketIndex, inputStreamPosition);
            }
            return this.outputBuffer.subarray(0, this.outputBufferPosition);
        };
        Compressor.prototype.findLongestMatch = function (matchedSequencePosition, bucketIndex) {
            var bucket = this.prefixHashTable.getArraySegmentForBucketIndex(bucketIndex, this.reusableArraySegmentObject);
            if (bucket == null)
                return null;
            var input = this.inputBuffer;
            var longestMatchDistance;
            var longestMatchLength = 0;
            for (var i = 0; i < bucket.length; i++) {
                var testedSequencePosition = bucket.getInReversedOrder(i) - this.inputBufferStreamOffset;
                var testedSequenceDistance = matchedSequencePosition - testedSequencePosition;
                var lengthToSurpass = void 0;
                if (longestMatchDistance === undefined)
                    lengthToSurpass = this.MinimumSequenceLength - 1;
                else if (longestMatchDistance < 128 && testedSequenceDistance >= 128)
                    lengthToSurpass = longestMatchLength + (longestMatchLength >>> 1);
                else
                    lengthToSurpass = longestMatchLength;
                if (testedSequenceDistance > this.MaximumMatchDistance ||
                    lengthToSurpass >= this.MaximumSequenceLength ||
                    matchedSequencePosition + lengthToSurpass >= input.length)
                    break;
                if (input[testedSequencePosition + lengthToSurpass] !== input[matchedSequencePosition + lengthToSurpass])
                    continue;
                for (var offset = 0;; offset++) {
                    if (matchedSequencePosition + offset === input.length ||
                        input[testedSequencePosition + offset] !== input[matchedSequencePosition + offset]) {
                        if (offset > lengthToSurpass) {
                            longestMatchDistance = testedSequenceDistance;
                            longestMatchLength = offset;
                        }
                        break;
                    }
                    else if (offset === this.MaximumSequenceLength)
                        return { distance: testedSequenceDistance, length: this.MaximumSequenceLength };
                }
            }
            if (longestMatchDistance !== undefined)
                return { distance: longestMatchDistance, length: longestMatchLength };
            else
                return null;
        };
        Compressor.prototype.getBucketIndexForPrefix = function (startPosition) {
            return (this.inputBuffer[startPosition] * 7880599 +
                this.inputBuffer[startPosition + 1] * 39601 +
                this.inputBuffer[startPosition + 2] * 199 +
                this.inputBuffer[startPosition + 3]) % this.PrefixHashTableSize;
        };
        Compressor.prototype.outputPointerBytes = function (length, distance) {
            if (distance < 128) {
                this.outputRawByte(192 | length);
                this.outputRawByte(distance);
            }
            else {
                this.outputRawByte(224 | length);
                this.outputRawByte(distance >>> 8);
                this.outputRawByte(distance & 255);
            }
        };
        Compressor.prototype.outputRawByte = function (value) {
            this.outputBuffer[this.outputBufferPosition++] = value;
        };
        Compressor.prototype.cropAndAddNewBytesToInputBuffer = function (newInput) {
            if (this.inputBuffer === undefined) {
                this.inputBuffer = newInput;
                return 0;
            }
            else {
                var cropLength = Math.min(this.inputBuffer.length, this.MaximumMatchDistance);
                var cropStartOffset = this.inputBuffer.length - cropLength;
                this.inputBuffer = LZUTF8.CompressionCommon.getCroppedAndAppendedByteArray(this.inputBuffer, cropStartOffset, cropLength, newInput);
                this.inputBufferStreamOffset += cropStartOffset;
                return cropLength;
            }
        };
        return Compressor;
    }());
    LZUTF8.Compressor = Compressor;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var CompressorCustomHashTable = (function () {
        function CompressorCustomHashTable(bucketCount) {
            this.minimumBucketCapacity = 4;
            this.maximumBucketCapacity = 64;
            this.bucketLocators = new Uint32Array(bucketCount * 2);
            this.storage = new Uint32Array(bucketCount * 2);
            this.storageIndex = 1;
        }
        CompressorCustomHashTable.prototype.addValueToBucket = function (bucketIndex, valueToAdd) {
            bucketIndex <<= 1;
            if (this.storageIndex >= (this.storage.length >>> 1))
                this.compact();
            var startPosition = this.bucketLocators[bucketIndex];
            var length;
            if (startPosition === 0) {
                startPosition = this.storageIndex;
                length = 1;
                this.storage[this.storageIndex] = valueToAdd;
                this.storageIndex += this.minimumBucketCapacity;
            }
            else {
                length = this.bucketLocators[bucketIndex + 1];
                if (length === this.maximumBucketCapacity - 1)
                    length = this.truncateBucketToNewerElements(startPosition, length, this.maximumBucketCapacity / 2);
                var endPosition = startPosition + length;
                if (this.storage[endPosition] === 0) {
                    this.storage[endPosition] = valueToAdd;
                    if (endPosition === this.storageIndex)
                        this.storageIndex += length;
                }
                else {
                    LZUTF8.ArrayTools.copyElements(this.storage, startPosition, this.storage, this.storageIndex, length);
                    startPosition = this.storageIndex;
                    this.storageIndex += length;
                    this.storage[this.storageIndex++] = valueToAdd;
                    this.storageIndex += length;
                }
                length++;
            }
            this.bucketLocators[bucketIndex] = startPosition;
            this.bucketLocators[bucketIndex + 1] = length;
        };
        CompressorCustomHashTable.prototype.truncateBucketToNewerElements = function (startPosition, bucketLength, truncatedBucketLength) {
            var sourcePosition = startPosition + bucketLength - truncatedBucketLength;
            LZUTF8.ArrayTools.copyElements(this.storage, sourcePosition, this.storage, startPosition, truncatedBucketLength);
            LZUTF8.ArrayTools.zeroElements(this.storage, startPosition + truncatedBucketLength, bucketLength - truncatedBucketLength);
            return truncatedBucketLength;
        };
        CompressorCustomHashTable.prototype.compact = function () {
            var oldBucketLocators = this.bucketLocators;
            var oldStorage = this.storage;
            this.bucketLocators = new Uint32Array(this.bucketLocators.length);
            this.storageIndex = 1;
            for (var bucketIndex = 0; bucketIndex < oldBucketLocators.length; bucketIndex += 2) {
                var length_3 = oldBucketLocators[bucketIndex + 1];
                if (length_3 === 0)
                    continue;
                this.bucketLocators[bucketIndex] = this.storageIndex;
                this.bucketLocators[bucketIndex + 1] = length_3;
                this.storageIndex += Math.max(Math.min(length_3 * 2, this.maximumBucketCapacity), this.minimumBucketCapacity);
            }
            this.storage = new Uint32Array(this.storageIndex * 8);
            for (var bucketIndex = 0; bucketIndex < oldBucketLocators.length; bucketIndex += 2) {
                var sourcePosition = oldBucketLocators[bucketIndex];
                if (sourcePosition === 0)
                    continue;
                var destPosition = this.bucketLocators[bucketIndex];
                var length_4 = this.bucketLocators[bucketIndex + 1];
                LZUTF8.ArrayTools.copyElements(oldStorage, sourcePosition, this.storage, destPosition, length_4);
            }
        };
        CompressorCustomHashTable.prototype.getArraySegmentForBucketIndex = function (bucketIndex, outputObject) {
            bucketIndex <<= 1;
            var startPosition = this.bucketLocators[bucketIndex];
            if (startPosition === 0)
                return null;
            if (outputObject === undefined)
                outputObject = new LZUTF8.ArraySegment(this.storage, startPosition, this.bucketLocators[bucketIndex + 1]);
            return outputObject;
        };
        CompressorCustomHashTable.prototype.getUsedBucketCount = function () {
            return Math.floor(LZUTF8.ArrayTools.countNonzeroValuesInArray(this.bucketLocators) / 2);
        };
        CompressorCustomHashTable.prototype.getTotalElementCount = function () {
            var result = 0;
            for (var i = 0; i < this.bucketLocators.length; i += 2)
                result += this.bucketLocators[i + 1];
            return result;
        };
        return CompressorCustomHashTable;
    }());
    LZUTF8.CompressorCustomHashTable = CompressorCustomHashTable;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var CompressorSimpleHashTable = (function () {
        function CompressorSimpleHashTable(size) {
            this.maximumBucketCapacity = 64;
            this.buckets = new Array(size);
        }
        CompressorSimpleHashTable.prototype.addValueToBucket = function (bucketIndex, valueToAdd) {
            var bucket = this.buckets[bucketIndex];
            if (bucket === undefined) {
                this.buckets[bucketIndex] = [valueToAdd];
            }
            else {
                if (bucket.length === this.maximumBucketCapacity - 1)
                    LZUTF8.ArrayTools.truncateStartingElements(bucket, this.maximumBucketCapacity / 2);
                bucket.push(valueToAdd);
            }
        };
        CompressorSimpleHashTable.prototype.getArraySegmentForBucketIndex = function (bucketIndex, outputObject) {
            var bucket = this.buckets[bucketIndex];
            if (bucket === undefined)
                return null;
            if (outputObject === undefined)
                outputObject = new LZUTF8.ArraySegment(bucket, 0, bucket.length);
            return outputObject;
        };
        CompressorSimpleHashTable.prototype.getUsedBucketCount = function () {
            return LZUTF8.ArrayTools.countNonzeroValuesInArray(this.buckets);
        };
        CompressorSimpleHashTable.prototype.getTotalElementCount = function () {
            var currentSum = 0;
            for (var i = 0; i < this.buckets.length; i++) {
                if (this.buckets[i] !== undefined)
                    currentSum += this.buckets[i].length;
            }
            return currentSum;
        };
        return CompressorSimpleHashTable;
    }());
    LZUTF8.CompressorSimpleHashTable = CompressorSimpleHashTable;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Decompressor = (function () {
        function Decompressor() {
            this.MaximumMatchDistance = 32767;
            this.outputPosition = 0;
        }
        Decompressor.prototype.decompressBlockToString = function (input) {
            input = LZUTF8.BufferTools.convertToUint8ArrayIfNeeded(input);
            return LZUTF8.decodeUTF8(this.decompressBlock(input));
        };
        Decompressor.prototype.decompressBlock = function (input) {
            if (this.inputBufferRemainder) {
                input = LZUTF8.ArrayTools.concatUint8Arrays([this.inputBufferRemainder, input]);
                this.inputBufferRemainder = undefined;
            }
            var outputStartPosition = this.cropOutputBufferToWindowAndInitialize(Math.max(input.length * 4, 1024));
            for (var readPosition = 0, inputLength = input.length; readPosition < inputLength; readPosition++) {
                var inputValue = input[readPosition];
                if (inputValue >>> 6 != 3) {
                    this.outputByte(inputValue);
                    continue;
                }
                var sequenceLengthIdentifier = inputValue >>> 5;
                if (readPosition == inputLength - 1 ||
                    (readPosition == inputLength - 2 && sequenceLengthIdentifier == 7)) {
                    this.inputBufferRemainder = input.subarray(readPosition);
                    break;
                }
                if (input[readPosition + 1] >>> 7 === 1) {
                    this.outputByte(inputValue);
                }
                else {
                    var matchLength = inputValue & 31;
                    var matchDistance = void 0;
                    if (sequenceLengthIdentifier == 6) {
                        matchDistance = input[readPosition + 1];
                        readPosition += 1;
                    }
                    else {
                        matchDistance = (input[readPosition + 1] << 8) | (input[readPosition + 2]);
                        readPosition += 2;
                    }
                    var matchPosition = this.outputPosition - matchDistance;
                    for (var offset = 0; offset < matchLength; offset++)
                        this.outputByte(this.outputBuffer[matchPosition + offset]);
                }
            }
            this.rollBackIfOutputBufferEndsWithATruncatedMultibyteSequence();
            return LZUTF8.CompressionCommon.getCroppedBuffer(this.outputBuffer, outputStartPosition, this.outputPosition - outputStartPosition);
        };
        Decompressor.prototype.outputByte = function (value) {
            if (this.outputPosition === this.outputBuffer.length)
                this.outputBuffer = LZUTF8.ArrayTools.doubleByteArrayCapacity(this.outputBuffer);
            this.outputBuffer[this.outputPosition++] = value;
        };
        Decompressor.prototype.cropOutputBufferToWindowAndInitialize = function (initialCapacity) {
            if (!this.outputBuffer) {
                this.outputBuffer = new Uint8Array(initialCapacity);
                return 0;
            }
            var cropLength = Math.min(this.outputPosition, this.MaximumMatchDistance);
            this.outputBuffer = LZUTF8.CompressionCommon.getCroppedBuffer(this.outputBuffer, this.outputPosition - cropLength, cropLength, initialCapacity);
            this.outputPosition = cropLength;
            if (this.outputBufferRemainder) {
                for (var i = 0; i < this.outputBufferRemainder.length; i++)
                    this.outputByte(this.outputBufferRemainder[i]);
                this.outputBufferRemainder = undefined;
            }
            return cropLength;
        };
        Decompressor.prototype.rollBackIfOutputBufferEndsWithATruncatedMultibyteSequence = function () {
            for (var offset = 1; offset <= 4 && this.outputPosition - offset >= 0; offset++) {
                var value = this.outputBuffer[this.outputPosition - offset];
                if ((offset < 4 && (value >>> 3) === 30) ||
                    (offset < 3 && (value >>> 4) === 14) ||
                    (offset < 2 && (value >>> 5) === 6)) {
                    this.outputBufferRemainder = this.outputBuffer.subarray(this.outputPosition - offset, this.outputPosition);
                    this.outputPosition -= offset;
                    return;
                }
            }
        };
        return Decompressor;
    }());
    LZUTF8.Decompressor = Decompressor;
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Encoding;
    (function (Encoding) {
        var Base64;
        (function (Base64) {
            var charCodeMap = new Uint8Array([65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47]);
            var reverseCharCodeMap = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255]);
            var paddingCharacter = "=";
            var paddingCharCode = 61;
            Base64.encode = function (inputBytes) {
                if (!inputBytes || inputBytes.length == 0)
                    return "";
                if (LZUTF8.runningInNodeJS()) {
                    return (LZUTF8.BufferTools.uint8ArrayToBuffer(inputBytes)).toString("base64");
                }
                else {
                    return Base64.encodeWithJS(inputBytes);
                }
            };
            Base64.decode = function (base64String) {
                if (!base64String)
                    return new Uint8Array(0);
                if (LZUTF8.runningInNodeJS()) {
                    return LZUTF8.BufferTools.bufferToUint8Array(new Buffer(base64String, "base64"));
                }
                else {
                    return Base64.decodeWithJS(base64String);
                }
            };
            Base64.encodeWithJS = function (inputBytes, addPadding) {
                if (addPadding === void 0) { addPadding = true; }
                if (!inputBytes || inputBytes.length == 0)
                    return "";
                var map = charCodeMap;
                var output = new LZUTF8.StringBuilder();
                var uint24;
                for (var readPosition = 0, length_5 = inputBytes.length; readPosition < length_5; readPosition += 3) {
                    if (readPosition <= length_5 - 3) {
                        uint24 = inputBytes[readPosition] << 16 | inputBytes[readPosition + 1] << 8 | inputBytes[readPosition + 2];
                        output.appendCharCode(map[(uint24 >>> 18) & 63]);
                        output.appendCharCode(map[(uint24 >>> 12) & 63]);
                        output.appendCharCode(map[(uint24 >>> 6) & 63]);
                        output.appendCharCode(map[(uint24) & 63]);
                        uint24 = 0;
                    }
                    else if (readPosition === length_5 - 2) {
                        uint24 = inputBytes[readPosition] << 16 | inputBytes[readPosition + 1] << 8;
                        output.appendCharCode(map[(uint24 >>> 18) & 63]);
                        output.appendCharCode(map[(uint24 >>> 12) & 63]);
                        output.appendCharCode(map[(uint24 >>> 6) & 63]);
                        if (addPadding)
                            output.appendCharCode(paddingCharCode);
                    }
                    else if (readPosition === length_5 - 1) {
                        uint24 = inputBytes[readPosition] << 16;
                        output.appendCharCode(map[(uint24 >>> 18) & 63]);
                        output.appendCharCode(map[(uint24 >>> 12) & 63]);
                        if (addPadding) {
                            output.appendCharCode(paddingCharCode);
                            output.appendCharCode(paddingCharCode);
                        }
                    }
                }
                return output.getOutputString();
            };
            Base64.decodeWithJS = function (base64String, outputBuffer) {
                if (!base64String || base64String.length == 0)
                    return new Uint8Array(0);
                var lengthModulo4 = base64String.length % 4;
                if (lengthModulo4 === 1)
                    throw new Error("Invalid Base64 string: length % 4 == 1");
                else if (lengthModulo4 === 2)
                    base64String += paddingCharacter + paddingCharacter;
                else if (lengthModulo4 === 3)
                    base64String += paddingCharacter;
                if (!outputBuffer)
                    outputBuffer = new Uint8Array(base64String.length);
                var outputPosition = 0;
                var length = base64String.length;
                for (var i = 0; i < length; i += 4) {
                    var uint24 = (reverseCharCodeMap[base64String.charCodeAt(i)] << 18) |
                        (reverseCharCodeMap[base64String.charCodeAt(i + 1)] << 12) |
                        (reverseCharCodeMap[base64String.charCodeAt(i + 2)] << 6) |
                        (reverseCharCodeMap[base64String.charCodeAt(i + 3)]);
                    outputBuffer[outputPosition++] = (uint24 >>> 16) & 255;
                    outputBuffer[outputPosition++] = (uint24 >>> 8) & 255;
                    outputBuffer[outputPosition++] = (uint24) & 255;
                }
                if (base64String.charCodeAt(length - 1) == paddingCharCode)
                    outputPosition--;
                if (base64String.charCodeAt(length - 2) == paddingCharCode)
                    outputPosition--;
                return outputBuffer.subarray(0, outputPosition);
            };
        })(Base64 = Encoding.Base64 || (Encoding.Base64 = {}));
    })(Encoding = LZUTF8.Encoding || (LZUTF8.Encoding = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Encoding;
    (function (Encoding) {
        var BinaryString;
        (function (BinaryString) {
            BinaryString.encode = function (input) {
                if (input == null)
                    throw new TypeError("BinaryString.encode: undefined or null input received");
                if (input.length === 0)
                    return "";
                var inputLength = input.length;
                var outputStringBuilder = new LZUTF8.StringBuilder();
                var remainder = 0;
                var state = 1;
                for (var i = 0; i < inputLength; i += 2) {
                    var value = void 0;
                    if (i == inputLength - 1)
                        value = (input[i] << 8);
                    else
                        value = (input[i] << 8) | input[i + 1];
                    outputStringBuilder.appendCharCode((remainder << (16 - state)) | value >>> state);
                    remainder = value & ((1 << state) - 1);
                    if (state === 15) {
                        outputStringBuilder.appendCharCode(remainder);
                        remainder = 0;
                        state = 1;
                    }
                    else {
                        state += 1;
                    }
                    if (i >= inputLength - 2)
                        outputStringBuilder.appendCharCode(remainder << (16 - state));
                }
                outputStringBuilder.appendCharCode(32768 | (inputLength % 2));
                return outputStringBuilder.getOutputString();
            };
            BinaryString.decode = function (input) {
                if (typeof input !== "string")
                    throw new TypeError("BinaryString.decode: invalid input type");
                if (input == "")
                    return new Uint8Array(0);
                var output = new Uint8Array(input.length * 3);
                var outputPosition = 0;
                var appendToOutput = function (value) {
                    output[outputPosition++] = value >>> 8;
                    output[outputPosition++] = value & 255;
                };
                var remainder = 0;
                var state = 0;
                for (var i = 0; i < input.length; i++) {
                    var value = input.charCodeAt(i);
                    if (value >= 32768) {
                        if (value == (32768 | 1))
                            outputPosition--;
                        state = 0;
                        continue;
                    }
                    if (state == 0) {
                        remainder = value;
                    }
                    else {
                        appendToOutput((remainder << state) | (value >>> (15 - state)));
                        remainder = value & ((1 << (15 - state)) - 1);
                    }
                    if (state == 15)
                        state = 0;
                    else
                        state += 1;
                }
                return output.subarray(0, outputPosition);
            };
        })(BinaryString = Encoding.BinaryString || (Encoding.BinaryString = {}));
    })(Encoding = LZUTF8.Encoding || (LZUTF8.Encoding = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Encoding;
    (function (Encoding) {
        var CodePoint;
        (function (CodePoint) {
            CodePoint.encodeFromString = function (str, position) {
                var charCode = str.charCodeAt(position);
                if (charCode < 0xD800 || charCode > 0xDBFF)
                    return charCode;
                else {
                    var nextCharCode = str.charCodeAt(position + 1);
                    if (nextCharCode >= 0xDC00 && nextCharCode <= 0xDFFF)
                        return 0x10000 + (((charCode - 0xD800) << 10) + (nextCharCode - 0xDC00));
                    else
                        throw new Error("getUnicodeCodePoint: Received a lead surrogate character, char code " + charCode + ", followed by " + nextCharCode + ", which is not a trailing surrogate character code.");
                }
            };
            CodePoint.decodeToString = function (codePoint) {
                if (codePoint <= 0xFFFF)
                    return String.fromCharCode(codePoint);
                else if (codePoint <= 0x10FFFF)
                    return String.fromCharCode(0xD800 + ((codePoint - 0x10000) >>> 10), 0xDC00 + ((codePoint - 0x10000) & 1023));
                else
                    throw new Error("getStringFromUnicodeCodePoint: A code point of " + codePoint + " cannot be encoded in UTF-16");
            };
        })(CodePoint = Encoding.CodePoint || (Encoding.CodePoint = {}));
    })(Encoding = LZUTF8.Encoding || (LZUTF8.Encoding = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Encoding;
    (function (Encoding) {
        var DecimalString;
        (function (DecimalString) {
            var lookupTable = ["000", "001", "002", "003", "004", "005", "006", "007", "008", "009", "010", "011", "012", "013", "014", "015", "016", "017", "018", "019", "020", "021", "022", "023", "024", "025", "026", "027", "028", "029", "030", "031", "032", "033", "034", "035", "036", "037", "038", "039", "040", "041", "042", "043", "044", "045", "046", "047", "048", "049", "050", "051", "052", "053", "054", "055", "056", "057", "058", "059", "060", "061", "062", "063", "064", "065", "066", "067", "068", "069", "070", "071", "072", "073", "074", "075", "076", "077", "078", "079", "080", "081", "082", "083", "084", "085", "086", "087", "088", "089", "090", "091", "092", "093", "094", "095", "096", "097", "098", "099", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252", "253", "254", "255"];
            DecimalString.encode = function (binaryBytes) {
                var resultArray = [];
                for (var i = 0; i < binaryBytes.length; i++)
                    resultArray.push(lookupTable[binaryBytes[i]]);
                return resultArray.join(" ");
            };
        })(DecimalString = Encoding.DecimalString || (Encoding.DecimalString = {}));
    })(Encoding = LZUTF8.Encoding || (LZUTF8.Encoding = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Encoding;
    (function (Encoding) {
        var StorageBinaryString;
        (function (StorageBinaryString) {
            StorageBinaryString.encode = function (input) {
                return Encoding.BinaryString.encode(input).replace(/\0/g, '\u8002');
            };
            StorageBinaryString.decode = function (input) {
                return Encoding.BinaryString.decode(input.replace(/\u8002/g, '\0'));
            };
        })(StorageBinaryString = Encoding.StorageBinaryString || (Encoding.StorageBinaryString = {}));
    })(Encoding = LZUTF8.Encoding || (LZUTF8.Encoding = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    var Encoding;
    (function (Encoding) {
        var UTF8;
        (function (UTF8) {
            var nativeTextEncoder;
            var nativeTextDecoder;
            UTF8.encode = function (str) {
                if (!str || str.length == 0)
                    return new Uint8Array(0);
                if (LZUTF8.runningInNodeJS()) {
                    return LZUTF8.BufferTools.bufferToUint8Array(new Buffer(str, "utf8"));
                }
                else if (UTF8.createNativeTextEncoderAndDecoderIfAvailable()) {
                    return nativeTextEncoder.encode(str);
                }
                else {
                    return UTF8.encodeWithJS(str);
                }
            };
            UTF8.decode = function (utf8Bytes) {
                if (!utf8Bytes || utf8Bytes.length == 0)
                    return "";
                if (LZUTF8.runningInNodeJS()) {
                    return LZUTF8.BufferTools.uint8ArrayToBuffer(utf8Bytes).toString("utf8");
                }
                else if (UTF8.createNativeTextEncoderAndDecoderIfAvailable()) {
                    return nativeTextDecoder.decode(utf8Bytes);
                }
                else {
                    return UTF8.decodeWithJS(utf8Bytes);
                }
            };
            UTF8.encodeWithJS = function (str, outputArray) {
                if (!str || str.length == 0)
                    return new Uint8Array(0);
                if (!outputArray)
                    outputArray = new Uint8Array(str.length * 4);
                var writeIndex = 0;
                for (var readIndex = 0; readIndex < str.length; readIndex++) {
                    var charCode = Encoding.CodePoint.encodeFromString(str, readIndex);
                    if (charCode <= 0x7F) {
                        outputArray[writeIndex++] = charCode;
                    }
                    else if (charCode <= 0x7FF) {
                        outputArray[writeIndex++] = 0xC0 | (charCode >>> 6);
                        outputArray[writeIndex++] = 0x80 | (charCode & 63);
                    }
                    else if (charCode <= 0xFFFF) {
                        outputArray[writeIndex++] = 0xE0 | (charCode >>> 12);
                        outputArray[writeIndex++] = 0x80 | ((charCode >>> 6) & 63);
                        outputArray[writeIndex++] = 0x80 | (charCode & 63);
                    }
                    else if (charCode <= 0x10FFFF) {
                        outputArray[writeIndex++] = 0xF0 | (charCode >>> 18);
                        outputArray[writeIndex++] = 0x80 | ((charCode >>> 12) & 63);
                        outputArray[writeIndex++] = 0x80 | ((charCode >>> 6) & 63);
                        outputArray[writeIndex++] = 0x80 | (charCode & 63);
                        readIndex++;
                    }
                    else
                        throw new Error("Invalid UTF-16 string: Encountered a character unsupported by UTF-8/16 (RFC 3629)");
                }
                return outputArray.subarray(0, writeIndex);
            };
            UTF8.decodeWithJS = function (utf8Bytes, startOffset, endOffset) {
                if (startOffset === void 0) { startOffset = 0; }
                if (!utf8Bytes || utf8Bytes.length == 0)
                    return "";
                if (endOffset === undefined)
                    endOffset = utf8Bytes.length;
                var output = new LZUTF8.StringBuilder();
                var outputCodePoint;
                var leadByte;
                for (var readIndex = startOffset, length_6 = endOffset; readIndex < length_6;) {
                    leadByte = utf8Bytes[readIndex];
                    if ((leadByte >>> 7) === 0) {
                        outputCodePoint = leadByte;
                        readIndex += 1;
                    }
                    else if ((leadByte >>> 5) === 6) {
                        if (readIndex + 1 >= endOffset)
                            throw new Error("Invalid UTF-8 stream: Truncated codepoint sequence encountered at position " + readIndex);
                        outputCodePoint = ((leadByte & 31) << 6) | (utf8Bytes[readIndex + 1] & 63);
                        readIndex += 2;
                    }
                    else if ((leadByte >>> 4) === 14) {
                        if (readIndex + 2 >= endOffset)
                            throw new Error("Invalid UTF-8 stream: Truncated codepoint sequence encountered at position " + readIndex);
                        outputCodePoint = ((leadByte & 15) << 12) | ((utf8Bytes[readIndex + 1] & 63) << 6) | (utf8Bytes[readIndex + 2] & 63);
                        readIndex += 3;
                    }
                    else if ((leadByte >>> 3) === 30) {
                        if (readIndex + 3 >= endOffset)
                            throw new Error("Invalid UTF-8 stream: Truncated codepoint sequence encountered at position " + readIndex);
                        outputCodePoint = ((leadByte & 7) << 18) | ((utf8Bytes[readIndex + 1] & 63) << 12) | ((utf8Bytes[readIndex + 2] & 63) << 6) | (utf8Bytes[readIndex + 3] & 63);
                        readIndex += 4;
                    }
                    else
                        throw new Error("Invalid UTF-8 stream: An invalid lead byte value encountered at position " + readIndex);
                    output.appendCodePoint(outputCodePoint);
                }
                return output.getOutputString();
            };
            UTF8.createNativeTextEncoderAndDecoderIfAvailable = function () {
                if (nativeTextEncoder)
                    return true;
                if (typeof TextEncoder == "function") {
                    nativeTextEncoder = new TextEncoder("utf-8");
                    nativeTextDecoder = new TextDecoder("utf-8");
                    return true;
                }
                else
                    return false;
            };
        })(UTF8 = Encoding.UTF8 || (Encoding.UTF8 = {}));
    })(Encoding = LZUTF8.Encoding || (LZUTF8.Encoding = {}));
})(LZUTF8 || (LZUTF8 = {}));
var LZUTF8;
(function (LZUTF8) {
    function compress(input, options) {
        if (options === void 0) { options = {}; }
        if (input == null)
            throw new TypeError("compress: undefined or null input received");
        var inputEncoding = LZUTF8.CompressionCommon.detectCompressionSourceEncoding(input);
        options = LZUTF8.ObjectTools.override({ inputEncoding: inputEncoding, outputEncoding: "ByteArray" }, options);
        var compressor = new LZUTF8.Compressor();
        var compressedBytes = compressor.compressBlock(input);
        return LZUTF8.CompressionCommon.encodeCompressedBytes(compressedBytes, options.outputEncoding);
    }
    LZUTF8.compress = compress;
    function decompress(input, options) {
        if (options === void 0) { options = {}; }
        if (input == null)
            throw new TypeError("decompress: undefined or null input received");
        options = LZUTF8.ObjectTools.override({ inputEncoding: "ByteArray", outputEncoding: "String" }, options);
        var inputBytes = LZUTF8.CompressionCommon.decodeCompressedBytes(input, options.inputEncoding);
        var decompressor = new LZUTF8.Decompressor();
        var decompressedBytes = decompressor.decompressBlock(inputBytes);
        return LZUTF8.CompressionCommon.encodeDecompressedBytes(decompressedBytes, options.outputEncoding);
    }
    LZUTF8.decompress = decompress;
    function compressAsync(input, options, callback) {
        if (callback == null)
            callback = function () { };
        var inputEncoding;
        try {
            inputEncoding = LZUTF8.CompressionCommon.detectCompressionSourceEncoding(input);
        }
        catch (e) {
            callback(undefined, e);
            return;
        }
        options = LZUTF8.ObjectTools.override({
            inputEncoding: inputEncoding,
            outputEncoding: "ByteArray",
            useWebWorker: true,
            blockSize: 65536
        }, options);
        LZUTF8.enqueueImmediate(function () {
            if (options.useWebWorker && LZUTF8.WebWorker.createGlobalWorkerIfNeeded()) {
                LZUTF8.WebWorker.compressAsync(input, options, callback);
            }
            else {
                LZUTF8.AsyncCompressor.compressAsync(input, options, callback);
            }
        });
    }
    LZUTF8.compressAsync = compressAsync;
    function decompressAsync(input, options, callback) {
        if (callback == null)
            callback = function () { };
        if (input == null) {
            callback(undefined, new TypeError("decompressAsync: undefined or null input received"));
            return;
        }
        options = LZUTF8.ObjectTools.override({
            inputEncoding: "ByteArray",
            outputEncoding: "String",
            useWebWorker: true,
            blockSize: 65536
        }, options);
        var normalizedInput = LZUTF8.BufferTools.convertToUint8ArrayIfNeeded(input);
        LZUTF8.EventLoop.enqueueImmediate(function () {
            if (options.useWebWorker && LZUTF8.WebWorker.createGlobalWorkerIfNeeded()) {
                LZUTF8.WebWorker.decompressAsync(normalizedInput, options, callback);
            }
            else {
                LZUTF8.AsyncDecompressor.decompressAsync(input, options, callback);
            }
        });
    }
    LZUTF8.decompressAsync = decompressAsync;
    function createCompressionStream() {
        return LZUTF8.AsyncCompressor.createCompressionStream();
    }
    LZUTF8.createCompressionStream = createCompressionStream;
    function createDecompressionStream() {
        return LZUTF8.AsyncDecompressor.createDecompressionStream();
    }
    LZUTF8.createDecompressionStream = createDecompressionStream;
    function encodeUTF8(str) {
        return LZUTF8.Encoding.UTF8.encode(str);
    }
    LZUTF8.encodeUTF8 = encodeUTF8;
    function decodeUTF8(input) {
        return LZUTF8.Encoding.UTF8.decode(input);
    }
    LZUTF8.decodeUTF8 = decodeUTF8;
    function encodeBase64(input) {
        return LZUTF8.Encoding.Base64.encode(input);
    }
    LZUTF8.encodeBase64 = encodeBase64;
    function decodeBase64(str) {
        return LZUTF8.Encoding.Base64.decode(str);
    }
    LZUTF8.decodeBase64 = decodeBase64;
    function encodeBinaryString(input) {
        return LZUTF8.Encoding.BinaryString.encode(input);
    }
    LZUTF8.encodeBinaryString = encodeBinaryString;
    function decodeBinaryString(str) {
        return LZUTF8.Encoding.BinaryString.decode(str);
    }
    LZUTF8.decodeBinaryString = decodeBinaryString;
    function encodeStorageBinaryString(input) {
        return LZUTF8.Encoding.StorageBinaryString.encode(input);
    }
    LZUTF8.encodeStorageBinaryString = encodeStorageBinaryString;
    function decodeStorageBinaryString(str) {
        return LZUTF8.Encoding.StorageBinaryString.decode(str);
    }
    LZUTF8.decodeStorageBinaryString = decodeStorageBinaryString;
})(LZUTF8 || (LZUTF8 = {}));